熔化 pandas 包含字典列的数据框,这样字典值也被熔化
Melt pandas dataframe containing column of dictionaries such that the dictionary values are also melted
这不是重复的
这个问题: 没有回答这个 post 中的问题。我在这个 post 的末尾包含了一种将字典列转换为数据框的方法,这不是我在这里发现的困难。
设置
给定以下数据:
d1 = {'a' : 12, 'b' : 44}
d2 = {'this' : 9, 'that' : 33, 'there' : 82}
d3 = {'x' : 19, 'y' : 38, 'z' : 12, 't' : 90}
df = pd.DataFrame(dict(
var_1 = [1,2,3],
var_2 = ['one', 'two', 'four'],
var_3 = [d1, d2, d3]
))
看起来像:
var_1 var_2 var_3
0 1 one {'a': 12, 'b': 44}
1 2 two {'this': 9, 'that': 33, 'there': 82}
2 3 four {'x': 19, 'y': 38, 'z': 12, 't': 90}
我希望能够 .melt
,特别是 id_vars
还从 var_3
列中提取了字典。
仅使用 第一行:
var_1 var_2 var_3
0 1 one {'a': 12, 'b': 44}
预期的中期结果为:
var_1 var_2 key value
0 1 one a 12
1 1 one b 44
融化后会是:
# using df.melt(id_vars = ['var_1', 'var_2'])
var_1 var_2 variable value
0 1 one key a
1 1 one key b
2 1 one value 12
3 1 one value 44
我想对所有数据执行此操作。
尝试
老实说,我不太确定该怎么做。
# make key : value dataframe
row_i = 0
col_i = 2
key_value_df = (pd.DataFrame( df.iloc[ row_i, col_i], index= [0 ] )
.T.reset_index()
.rename(columns = {'index' : 'key', 0 : 'value'})
)
data_thing = (pd.concat( [pd.DataFrame(df.iloc[ 0 , [0,1]]
.to_dict(), index=[0])] * len(key_value_df) ))
然后
data_thing.join(key_value_df).reset_index(drop=True)
会给
var_1 var_2 key value
0 1 one a 12
1 1 one a 12
但这感觉它可以得到显着改善,我不确定是否将它推广到其他行。
编辑
我可以使用诸如
之类的东西将一列字典作为数据框
all_keys = functools.reduce(lambda x,y: x+y , [list(x.keys()) for x in var3])
all_values = functools.reduce(lambda x,y: x+y, [list(x.values()) for x in var3])
pd.DataFrame(dict( keys = all_keys, values = all_values ))
给予
keys values
0 a 12
1 b 44
2 this 9
3 that 33
4 there 82
5 x 19
6 y 38
7 z 12
8 t 90
但这并没有回答我提出的问题
def custom_melt(df):
vals = []
for row in df.itertuples():
for k, v in row.var_3.items():
vals.append({'var_1': row.var_1,
'var_2': row.var_2,
'variable': 'key',
'value': k})
vals.append({'var_1': row.var_1,
'var_2': row.var_2,
'variable': 'value',
'value': v})
return pd.DataFrame(vals).sort_values(['var_1', 'var_2', 'variable'])
输出
>>>custom_melt(df)
var_1 var_2 variable value
0 1 one key a
2 1 one key b
1 1 one value 12
3 1 one value 44
使用您的df
import pandas as pd
var3 = pd.DataFrame(pd.DataFrame(df['var_3'].values.tolist()).stack().reset_index(level=1))
var3.columns = ['keys','values']
print(var3)
keys values
0 a 12.0
0 b 44.0
1 this 9.0
1 that 33.0
1 there 82.0
2 x 19.0
2 y 38.0
2 z 12.0
2 t 90.0
df = df.join(var3)
print(df)
pd.json_normalize
- 这可能会更好
var3 = pd.DataFrame(pd.json_normalize(df.var_3).stack()).reset_index(level=1)
var3.columns = ['keys','values']
这不是重复的
这个问题:
设置
给定以下数据:
d1 = {'a' : 12, 'b' : 44}
d2 = {'this' : 9, 'that' : 33, 'there' : 82}
d3 = {'x' : 19, 'y' : 38, 'z' : 12, 't' : 90}
df = pd.DataFrame(dict(
var_1 = [1,2,3],
var_2 = ['one', 'two', 'four'],
var_3 = [d1, d2, d3]
))
看起来像:
var_1 var_2 var_3
0 1 one {'a': 12, 'b': 44}
1 2 two {'this': 9, 'that': 33, 'there': 82}
2 3 four {'x': 19, 'y': 38, 'z': 12, 't': 90}
我希望能够 .melt
,特别是 id_vars
还从 var_3
列中提取了字典。
仅使用 第一行:
var_1 var_2 var_3
0 1 one {'a': 12, 'b': 44}
预期的中期结果为:
var_1 var_2 key value
0 1 one a 12
1 1 one b 44
融化后会是:
# using df.melt(id_vars = ['var_1', 'var_2'])
var_1 var_2 variable value
0 1 one key a
1 1 one key b
2 1 one value 12
3 1 one value 44
我想对所有数据执行此操作。
尝试
老实说,我不太确定该怎么做。
# make key : value dataframe
row_i = 0
col_i = 2
key_value_df = (pd.DataFrame( df.iloc[ row_i, col_i], index= [0 ] )
.T.reset_index()
.rename(columns = {'index' : 'key', 0 : 'value'})
)
data_thing = (pd.concat( [pd.DataFrame(df.iloc[ 0 , [0,1]]
.to_dict(), index=[0])] * len(key_value_df) ))
然后
data_thing.join(key_value_df).reset_index(drop=True)
会给
var_1 var_2 key value
0 1 one a 12
1 1 one a 12
但这感觉它可以得到显着改善,我不确定是否将它推广到其他行。
编辑
我可以使用诸如
之类的东西将一列字典作为数据框all_keys = functools.reduce(lambda x,y: x+y , [list(x.keys()) for x in var3])
all_values = functools.reduce(lambda x,y: x+y, [list(x.values()) for x in var3])
pd.DataFrame(dict( keys = all_keys, values = all_values ))
给予
keys values
0 a 12
1 b 44
2 this 9
3 that 33
4 there 82
5 x 19
6 y 38
7 z 12
8 t 90
但这并没有回答我提出的问题
def custom_melt(df):
vals = []
for row in df.itertuples():
for k, v in row.var_3.items():
vals.append({'var_1': row.var_1,
'var_2': row.var_2,
'variable': 'key',
'value': k})
vals.append({'var_1': row.var_1,
'var_2': row.var_2,
'variable': 'value',
'value': v})
return pd.DataFrame(vals).sort_values(['var_1', 'var_2', 'variable'])
输出
>>>custom_melt(df)
var_1 var_2 variable value
0 1 one key a
2 1 one key b
1 1 one value 12
3 1 one value 44
使用您的df
import pandas as pd
var3 = pd.DataFrame(pd.DataFrame(df['var_3'].values.tolist()).stack().reset_index(level=1))
var3.columns = ['keys','values']
print(var3)
keys values
0 a 12.0
0 b 44.0
1 this 9.0
1 that 33.0
1 there 82.0
2 x 19.0
2 y 38.0
2 z 12.0
2 t 90.0
df = df.join(var3)
print(df)
pd.json_normalize
- 这可能会更好
var3 = pd.DataFrame(pd.json_normalize(df.var_3).stack()).reset_index(level=1)
var3.columns = ['keys','values']