Reputation: 435
I have a pandas dataframe with a 'metadata' column that should contain a dictionary as value. However, some values are missing and set to NaN. I would like this to be {} instead. Sometimes, the entire column is missing and initializing it to {} is also problematic.
For adding the column
tspd['metadata'] = {} # fails
tspd['metadata'] = [{} for _ in tspd.index] # works
For filling missing values
tspd['metadata'].replace(np.nan,{}) # does nothing
tspd['metadata'].fillna({}) # likewise does nothing
tspd.loc[tspd['metadata'].isna(), 'metadata'] = {} # error
tspd['metadata'] = tspd['metadata'].where(~tspd['metadata'].isna(), other={}) # this sets the NaN values to <built-in method values of dict object>
So adding the column works, but is a bit ugly. Replacing the values without some (slow) loop seems not possible.
Upvotes: 4
Views: 2953
Reputation: 863226
You can use np.nan == np.nan
is False
, so for replace missing values is possible use:
tspd = pd.DataFrame({'a': [0,1,2], 'metadata':[{'a':'s'}, np.nan, {'d':'e'}]})
tspd['metadata'] = tspd['metadata'].apply(lambda x: {} if x != x else x)
print(tspd)
a metadata
0 0 {'a': 's'}
1 1 {}
2 2 {'d': 'e'}
Or:
tspd['metadata'] = [{} if x != x else x for x in tspd['metadata']]
Upvotes: 8
Reputation: 323326
Do not using [{}] * len(tspd)
tspd['metadata'] = [{}for x in range(len(tspd))]
tspd
Out[326]:
a metadata
0 0 {}
1 1 {}
2 2 {}
Detail
tspd['metadata'] = [{}] * len(tspd)
tspd['metadata'].iloc[0]['lll']=1
tspd # see all duplicated here ,since they are the same copy
Out[324]:
a metadata
0 0 {'lll': 1}
1 1 {'lll': 1}
2 2 {'lll': 1}
Do it one by one , each time create the iid {}
tspd['metadata'] = [{}for x in range(len(tspd))]
tspd
Out[326]:
a metadata
0 0 {}
1 1 {}
2 2 {}
tspd['metadata'].iloc[0]['lll']=1
tspd
Out[328]:
a metadata
0 0 {'lll': 1}
1 1 {}
2 2 {}
Upvotes: 2