根据 3 列以上的 df 列进行分组

问题描述 投票:0回答:1

我有一个 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 的方法。或者任何其他方式来实现这一点。

提前致谢。

python pandas dataframe
1个回答
0
投票

您可以使用单个

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 转换为经典 dict
def 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']}}}}
© www.soinside.com 2019 - 2024. All rights reserved.