我有一个4列的DataFrame
Subject_id Subject Time Score
Subject_1 Math Day 1
Subject_1 Math Night 2
Subject_1 Music Day 3
Subject_1 Music Night 4
Subject_2 Math Day 5
Subject_2 Math Night 6
Subject_2 Music Day 7
Subject_2 Music Night 8
我想按层次结构对这些列进行分组,然后将它们转换为字典,如下所示:
result = {
'Subject_1': {
'Math': {
'Day': 1,
'Night': 2
},
'Music': {
'Day': 3,
'Night': 4
}
}
'Subject_2': {
'Math': {
'Day': 5,
'Night': 6
},
'Music': {
'Day': 7,
'Night': 8
}
}
}
我设法使用pivot
少了一列并获得了所需的结果
df.pivot('Subject_id', 'Subject', 'Score').to_dict('index')
但是,如果我再尝试一个列(一级深层词典)
df.pivot('Subject_id', 'Subject', 'Time', 'Score').to_dict('index')
我收到错误:
TypeError: pivot() takes at most 4 arguments (5 given)
我同样尝试使用带有3列lambda函数的groupby
:
df.groupby('Subject_id')
.apply(lambda x: dict(zip(x['Subject'],x['Score'])))
.to_dict()
但我无法通过4列获得所需的结果。
有没有办法可以提供任意数量的列并将它们转换为分层字典?
喜欢按特定的层次结构顺序对多个字段进行分组。
答案 0 :(得分:3)
这是一种方式
In [86]: {k: g.pivot('Subject', 'Time', 'Score').to_dict('index')
for k, g in df.groupby('Subject_id')}
Out[86]:
{'Subject_1': {'Math': {'Day': 1, 'Night': 2},
'Music': {'Day': 3, 'Night': 4}},
'Subject_2': {'Math': {'Day': 5, 'Night': 6},
'Music': {'Day': 7, 'Night': 8}}}
答案 1 :(得分:1)
defaultdict
方法。
def rec_dd():
return defaultdict(rec_dd)
dd = rec_dd() # defaultdict for arbitrary depth
tuple_d = df.set_index(['Subject_id', 'Subject', 'Time']).to_dict()["Score"]
for k, v in tuple_d.items():
dd[k[0]][k[1]][k[2]] = v
defaultdict(<function __main__.rec_dd>,
{'Subject_1': defaultdict(<function __main__.rec_dd>,
{'Math': defaultdict(<function __main__.rec_dd>,
{'Day': 1, 'Night': 2}),
'Music': defaultdict(<function __main__.rec_dd>,
{'Day': 3, 'Night': 4})}),
'Subject_2': defaultdict(<function __main__.rec_dd>,
{'Math': defaultdict(<function __main__.rec_dd>,
{'Day': 5, 'Night': 6}),
'Music': defaultdict(<function __main__.rec_dd>,
{'Day': 7, 'Night': 8})})})
方法rec_dd
来自defaultdict of defaultdict, nested
如果您不想要defaultdict
,可以尝试以下
import json
d = json.loads(json.dumps(dd))
{'Subject_1': {'Math': {'Day': 1, 'Night': 2},
'Music': {'Day': 3, 'Night': 4}},
'Subject_2': {'Math': {'Day': 5, 'Night': 6},
'Music': {'Day': 7, 'Night': 8}}}
将defaultdict
转换为dict
的方法取自Python: convert defaultdict to dict