我有一个 df,它有 3 列,可以说 Region、Country 和 AREA_CODE。
Region Country AREA_CODE AREA_SUB_CODE_1 AREA_SUB_CODE_2
===========================================================================
AMER US A1 A1_US_1 A1_US_2
AMER CANADA A1 A1_CA_1 A1_CA_2
AMER US B1 B1_US_1 B1_US_2
AMER US A1 A1_US_1 A1_US_2
有没有办法获取 AREA_SUB_CODE_1 和 AREA_SUB_CODE_2 的输出列表作为每个前一列值下的列表。像下面这样的东西
{
"AREA_SUB_CODE_1": {
"AMER": {
"US": {
"A1": ["A1_US_1"],
"B1": ["B1_US_1"]
},
"CANADA": {
"A1": ["A1_CA_1"],
}
}
},
"AREA_SUB_CODE_2": {
"AMER": {
"US": {
"A1": {
"A1_US_1": ["A1_US_2"]
},
"B1": {
"B1_US_1": ["B1_US_2"]
},
"CANADA": {
"A1": {
"A1_CA_1": ["A1_CA_2"],
}
}
}
},
}
到目前为止,我已经尝试在 3 列上进行分组,它是有效的,
for (k1, k2), v in df.groupby(['Region', 'Country'])['AREA_CODE']:
tTmp.setdefault(k1, {})[k2] = sorted(v.unique())
但是当我尝试按 4 列进行分组时,它会抛出错误 需要解压的值太多(预期为 2)
for (k1, k2), v in df.groupby(['Region', 'Country', 'AREA_CODE'])['AREA_SUB_CODE_1']:
tTmp.setdefault(k1, {})[k2] = sorted(v.unique())
请建议我一种如何对 4 列和 5 列应用 groupby 的方法。或者任何其他方式来实现这一点。
提前致谢。
groupby
和递归 defaultdict
:
from collections import defaultdict
d = lambda: defaultdict(d)
out = d()
for (k1, k2, k3), g in (df.melt(['Region', 'Country', 'AREA_CODE'])
.set_index('AREA_CODE')
.groupby(['variable', 'Region', 'Country'])
[['value']]
):
print(keys)
out[k1][k2][k3] = g.T.to_dict('list')
然后,如果需要,可以使用 this Recipe:
将嵌套的 defaultdict 转换为经典 dictdef default_to_regular(d):
if isinstance(d, defaultdict):
d = {k: default_to_regular(v) for k, v in d.items()}
return d
out = default_to_regular(out)
输出:
{'AREA_SUB_CODE_1': {'AMER': {'CANADA': {'A1': ['A1_CA_1']},
'US': {'A1': ['A1_US_1'],
'B1': ['B1_US_1']}}},
'AREA_SUB_CODE_2': {'AMER': {'CANADA': {'A1': ['A1_CA_2']},
'US': {'A1': ['A1_US_2'],
'B1': ['B1_US_2']}}}}