为了账号安全,请及时绑定邮箱和手机立即绑定

从 Pandas DataFrame 创建嵌套 JSON,并将分组行作为最深嵌套内的属性

从 Pandas DataFrame 创建嵌套 JSON,并将分组行作为最深嵌套内的属性

哔哔one 2023-07-27 10:08:37
我正在寻找一种解决方案来构建嵌套的 dict / JSON,其中最后三列"name"、"color"、"amount"作为“product”列表中的属性。cat1-cat3列中的值应该是键。提供的 DataFrame 如下所示:import pandas as pddf = pd.DataFrame({    'cat1': ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C'],    'cat2': ['BB', 'BB', 'BC', 'BB', 'BB', 'BB', 'BC', 'BC'],    'cat3': ['CC', 'CC', 'CD', 'CD', 'CD', 'CC', 'CD', 'CE'],    'name': ['P1', 'P2', 'P3', 'P1', 'P4', 'P1', 'P3','P6'],    'color': ['red', 'blue', 'green', 'green', 'yellow', 'red', 'blue', 'blue']    'amount': [132, 51, 12, 421, 55, 11, 123, 312]})这将是所需的输出:{   "A":{      "BB":{         "CC":{            "products":[               {                  "name":"P1",                  "color":"red",                  "amount":132               },               {                  "name":"P2",                  "color":"blue",                  "amount":51               }            ]         }      },      "BC":{         "CD":{            "products":[               {                  "name":"P3",                  "color":"green",                  "amount":12               }            ]         }      }   },   "B":{      "BB":{         "CD":{            "products":[               {                  "name":"P1",                  "color":"green",                  "amount":421               },               {                  "name":"P4",                  "color":"yellow",                  "amount":55               }            ]         }      }   },   "C":{      "BB":{         "CC":{            "products":[               {                  "name":"P1",                  "color":"red",                  "amount":11               }            ]         }      },      "BC":{         "CD":{            "products":[               {                  "name":"P3",                  "color":"blue",                  "amount":123               }            ]         },@BEN_YO为这个问题提供了一个递归解决方案,没有内积部分。
查看完整描述

3 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

如果其他方法可以的话,你可以尝试下面的方法,虽然有点脏(你可以尝试优化它)


cols = ['name','color','amount']

u = df[df.columns.difference(cols)].join(df[cols].agg(dict,1).rename('d'))

v = (u.groupby(['cat1','cat2','cat3'])['d'].agg(list).reset_index("cat3"))


v = v.groupby(v.index).apply(lambda x: dict(zip(x['cat3'],x['d'])))

v.index = pd.MultiIndex.from_tuples(v.index,names=['cat1','cat2'])

d = v.unstack(0).to_dict()

print(d)

{'A': {'BB': {'CC': [{'amount': 132, 'color': 'red', 'name': 'P1'},

                     {'amount': 51, 'color': 'blue', 'name': 'P2'}]},

       'BC': {'CD': [{'amount': 12, 'color': 'green', 'name': 'P3'}]}},

 'B': {'BB': {'CD': [{'amount': 421, 'color': 'green', 'name': 'P1'},

                     {'amount': 55, 'color': 'yellow', 'name': 'P4'}]},

       'BC': nan},

 'C': {'BB': {'CC': [{'amount': 11, 'color': 'red', 'name': 'P1'}]},

       'BC': {'CD': [{'amount': 123, 'color': 'blue', 'name': 'P3'}],

              'CE': [{'amount': 312, 'color': 'blue', 'name': 'P6'}]}}}


查看完整回答
反对 回复 2023-07-27
?
MMMHUHU

TA贡献1834条经验 获得超8个赞

我们可以groupby基于分组类别cat1递归cat2地cat3构建字典:


def set_val(d, k, v):

    if len(k) == 1:

        d[k[0]] = v

    else:

        d[k[0]] = set_val(d.get(k[0], {}), k[1:], v)

    return d



dct = {}

for k, g in df.groupby(['cat1', 'cat2', 'cat3']):

    set_val(dct, k, {'products': g[['name', 'color', 'amount']].to_dict('r')})

print(dct)


{'A': {'BB': {'CC': {'products': [{'amount': 132, 'color': 'red', 'name': 'P1'},

                                  {'amount': 51, 'color': 'blue', 'name': 'P2'}]}},

       'BC': {'CD': {'products': [{'amount': 12, 'color': 'green', 'name': 'P3'}]}}},

 'B': {'BB': {'CD': {'products': [{'amount': 421, 'color': 'green', 'name': 'P1'},

                                  {'amount': 55, 'color': 'yellow', 'name': 'P4'}]}}},

 'C': {'BB': {'CC': {'products': [{'amount': 11, 'color': 'red', 'name': 'P1'}]}},

       'BC': {'CD': {'products': [{'amount': 123, 'color': 'blue', 'name': 'P3'}]},

              'CE': {'products': [{'amount': 312, 'color': 'blue', 'name': 'P6'}]}}}}


查看完整回答
反对 回复 2023-07-27
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

def gen_nested_dict(dataframe, group, inner_key, inner_dict):

    def set_val(d, k2, v):

        if len(k2) == 1:

            d[k2[0]] = v

        else:

            d[k2[0]] = set_val(d.get(k2[0], {}), k2[1:], v)

        return d


    dct = {}

    for k, g in dataframe.groupby(group):

        set_val(dct, k, {inner_key: g[inner_dict].to_dict('records')})


    return dct


 mydct = gen_nested_dict(df, ['cat1', 'cat2', 'cat3'], 'products', ['name', 'color', 'amount'])



查看完整回答
反对 回复 2023-07-27
  • 3 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信