Pandas:将数据框转换为嵌套字典

Pandas: transforming dataframe to nested dictionary

我有这个数据框:

Month_Year  City_Name   Chain_Name Product_Name Product_Price
11-2021     London      Aldi       Pasta        2.33
11-2021     Bristol     Spar       Bananas      1.45
10-2021     London      Tesco      Olives       4.12
10-2021     Cardiff     Spar       Pasta        2.25

此数据框将显示在 nested collapsible 中,它将按以下顺序展开:

Date_month:
    City_Name:
         Shop_name:
             Product_name : Price

因此,我想将数据帧转换为以下结构:

{10-2021:
    {London:
        {Aldi:
            {Pasta:2.33}}},
    {Bristol:{
        {Spar:
            {Bananas:1.45}}}}

基本上我想 groupby 每个元素递归,从购买月份开始。我发现的最接近的是 中的解决方案,但由于字典不采用重复值,因为我可能在每一列中都有重复值。除此之外,我不确定使用字典是否是解决此问题的最佳答案。

我最好的猜测是我必须使用其他 DS 类型,例如某种类型的树,但找不到任何方法来做到这一点。

有什么建议吗?

您可以按除价格以外的所有列对数据框进行分组,然后循环创建字典:

# if more than one price for one product in a chain, then calculate mean:
grouped_df = df.groupby(['Month_Year', 'City_Name', 'Chain_Name', 'Product_Name']).agg('mean')

result = dict()
nested_dict = dict()

for index, value in grouped_df.itertuples():
    for i, key in enumerate(index):
        if i == 0:
            if not key in result:
                result[key] = {}
            nested_dict = result[key]
        elif i == len(index) - 1:
            nested_dict[key] = value
        else:
            if not key in nested_dict:
                nested_dict[key] = {}
            nested_dict = nested_dict[key]

print(json.dumps(result, indent=4))

将你的 df 更改为显示嵌套字典和均值计算:

  Month_Year City_Name Chain_Name Product_Name  Product_Price
0    11-2021    London       Aldi        Pasta           2.33
1    11-2021    London       Aldi        Pasta           2.35
2    11-2021    London       Aldi       Olives           3.99
3    11-2021   Bristol       Spar      Bananas           1.45
4    10-2021    London      Tesco       Olives           4.12
5    10-2021   Cardiff       Spar        Pasta           2.25

你得到输出:

{
    "10-2021": {
        "Cardiff": {
            "Spar": {
                "Pasta": 2.25
            }
        },
        "London": {
            "Tesco": {
                "Olives": 4.12
            }
        }
    },
    "11-2021": {
        "Bristol": {
            "Spar": {
                "Bananas": 1.45
            }
        },
        "London": {
            "Aldi": {
                "Olives": 3.99,
                "Pasta": 2.34
            }
        }
    }
}