I have a list of dicts that I want to populate by updating the dict if a match of several values within a dict is found in a pandas series. eg
lis_of_dicts = [{'A':'a', 'B':'b','C':'c', 'D':'d'},
{'A':'1', 'B':'2','C':'3','D':'4'},
{'A':'M','B':'N','C':'O','D':'P'}]
dd = {'col1':['b', 'M'], 'col2':['d','P'], 'col3':['7.5','29']}
df = pd.Dataframe(dd, columns = ['col1', 'col2', 'col3'])
pd_series = pd.Series(tuple(value) for value in df.values), index=df.index)
which generated:
0 (b, d, 7.5)
1 (M, P, 29)
Desired result:
[{'A':'a', 'B':'b','C':'c', 'val': '7.5','D':'d'},
{'A':'1', 'B':'2','C':'3', 'val':'NA', 'D':'4'},
{'A':'M','B':'N','C':'O','val':'29','D':'P'}]
I tried this but I could not even get the match so could not proceed:
for i in pd_series:
for x in lis_of_dicts:
if [x[key] == i[0] in x and [x[key] == i[1] in x for key in x]:
x.update({'val':'i[2]'})
else:
x.update({'val':'NA'})
I am unable to generate any result. Notice the order of the dict should remain the same except for the value been added should be before the last item in the dictionary.
I would go for a nested loop based solution:
>>> df_2 = pd.DataFrame(lis_of_dicts)
>>> df_2
A B C D
0 a b c d
1 1 2 3 4
2 M N O P
>>> cols = df_2.columns
>>> for ix, row in df_2.iterrows():
... for item in pd_series:
... if set(row[cols]) & set(item):
... df_2.loc[ix, 'val'] = item[2]
... break
... else:
... df_2.loc[ix, 'val'] = 'NA'
>>> df_2.to_dict('r')
[{'A': 'a', 'B': 'b', 'C': 'c', 'D': 'd', 'val': 7.5},
{'A': '1', 'B': '2', 'C': '3', 'D': '4', 'val': 'NA'},
{'A': 'M', 'B': 'N', 'C': 'O', 'D': 'P', 'val': 29}]
EDIT : It can be simplified, as follows:
output = []
for d in lis_of_dicts:
for item in pd_series:
if set(d.values()) & set(item):
d['val'] = item[2]
break
else:
d['val'] = 'NA'
output.append(d)
>>> output
[{'A': 'a', 'B': 'b', 'C': 'c', 'D': 'd', 'val': 7.5},
{'A': '1', 'B': '2', 'C': '3', 'D': '4', 'val': 'NA'},
{'A': 'M', 'B': 'N', 'C': 'O', 'D': 'P', 'val': 29}]
EDIT 2 :
NOTE: This will only reliably work in python version >= 3.7, as order is not guaranteed to be maintained in dict
s for lower versions.
To place val
in 2nd last element:
output = []
for d in lis_of_dicts:
last = d.popitem()
for item in pd_series:
if set(d.values()) & set(item):
d['val'] = item[2]
d.update([last])
break
else:
d['val'] = 'NA'
d.update([last])
output.append(d)
>>> output
[{'A': 'a', 'B': 'b', 'C': 'c', 'val': 7.5, 'D': 'd'},
{'A': '1', 'B': '2', 'C': '3', 'val': 'NA', 'D': '4'},
{'A': 'M', 'B': 'N', 'C': 'O', 'val': 29, 'D': 'P'}]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.