【问题标题】:How to convert pandas dataframe to nested dictionary如何将熊猫数据框转换为嵌套字典
【发布时间】:2017-06-19 07:29:50
【问题描述】:

我正在运行 Python 3.6 和 Pandas 0.19.2,并且有一个如下所示的 DataFrame:

Name      Chain        Food       Healthy  

George    McDonalds    burger     False
George    KFC          chicken    False
John      Wendys       burger     False
John      McDonalds    salad      True

我想将此数据框转换为如下所示的字典:

health_data = {'George': {'McDonalds': {'Food': 'burger', 'Healthy':False},
                          'KFC':       {'Food': 'chicken', 'Healthy':False}},
               'John':   {'Wendys':    {'Food': 'burger', 'Healthy':False},
                          'McDonalds': {'Food': 'salad', 'Healthy': True}}}

到目前为止,我的想法是:

  1. 使用df.groupby 对名称列进行分组
  2. 使用df.to_dict() 将数据框转换为字典,如下所示: health_data = input_data.set_index('Chain').T.to_dict()

想法?预先感谢您的帮助。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    使用字典理解和groupby的解决方案:

    {n: grp.loc[n].to_dict('index')
     for n, grp in df.set_index(['Name', 'Chain']).groupby(level='Name')}
    
    {'George': {'KFC': {'Food': 'chicken', 'Healthy': False},
      'McDonalds': {'Food': 'burger', 'Healthy': False}},
     'John': {'McDonalds': {'Food': 'salad', 'Healthy': True},
      'Wendys': {'Food': 'burger', 'Healthy': False}}}
    

    使用defaultdict的解决方案:

    from collections import defaultdict
    
    d = defaultdict(dict)
    
    for i, row in df.iterrows():
        d[row.Name][row.Chain] = row.drop(['Name', 'Chain']).to_dict()
    
    dict(d)
    
    {'George': {'KFC': {'Food': 'chicken', 'Healthy': False},
      'McDonalds': {'Food': 'burger', 'Healthy': False}},
     'John': {'McDonalds': {'Food': 'salad', 'Healthy': True},
      'Wendys': {'Food': 'burger', 'Healthy': False}}}
    

    【讨论】:

    • 喜欢使用 iterrows 和默认字典,尽管它比 group by 慢了一点点。这将允许您将多个循环链接在一起。另一种方法是使用多索引(但不适合本示例)
    【解决方案2】:

    我认为你很接近。

    使用groupbyto_dict

    df = df.groupby('Name')[['Chain','Food','Healthy']]
           .apply(lambda x: x.set_index('Chain').to_dict(orient='index'))
           .to_dict()
    
    print (df)
    {'George': {'KFC': {'Healthy': False, 'Food': 'chicken'}, 
               'McDonalds': {'Healthy': False, 'Food': 'burger'}}, 
    'John': {'McDonalds': {'Healthy': True, 'Food': 'salad'},
             'Wendys': {'Healthy': False, 'Food': 'burger'}}}
    

    【讨论】:

    • 非常感谢!这非常有效。一个小问题:答案的[['Chain','Food','Healthy']] 部分是做什么的?
    • 是过滤列,但是如果df中没有其他列,可以简化成df.groupby('Name').apply(lambda x: x.set_index('Chain').to_dict(orient='index')).to_dict()
    • 我一直在尝试这样做,没想到将 .to_dict 放在 lambda 中,一如既往地感谢 Jozi :)
    猜你喜欢
    • 2023-03-10
    • 2021-01-19
    • 2022-01-06
    • 2019-10-26
    • 1970-01-01
    • 2021-09-30
    • 2019-07-18
    • 2018-07-14
    • 2019-05-07
    相关资源
    最近更新 更多