【问题标题】:How to compress pandas DataFrame into a dictionary with unique keys and listed values?如何将 pandas DataFrame 压缩到具有唯一键和列出值的字典中?
【发布时间】:2020-03-03 10:33:45
【问题描述】:

我有以下示例 pandas DataFrame,其中有两列,NameAge

import pandas as pd

data = [['Alex',10],['Bob',12],['Barbara',25], ['Bob',72], 
    ['Clarke',13], ['Clarke',13], ['Destiny', 45]]

df = pd.DataFrame(data,columns=['Name','Age'], dtype=float)

print(df)
      Name   Age
0     Alex  10.0
1      Bob  12.0
2  Barbara  25.0
3      Bob  72.0
4   Clarke  13.0
5   Clarke  13.0
6  Destiny  45.0

我的最终目标是创建一个字典,其中每个键是名称,每个值是与 Name 关联的 Ages 列表。

所以,结尾字典应该是

final_result = {"Alex":[10], "Bob":[12, 72], "Barbara":[25], "Clarke":[13], "Destiny":[45]} 

我的做法:

我可以尝试遍历数据框以创建列表,并重命名列:

for name in df.Name.unique():
    list_attributes = []
    for i in df.loc[df.Age == name].Age.unique()
        list_attributes.append(i)
    df['List_Column'] = list_attributes

但这很复杂。最有效的方法是什么?

【问题讨论】:

    标签: python pandas list


    【解决方案1】:

    选项 1groupby().apply(list)

    df.groupby('Name')['Age'].apply(list).to_dict()
    # 4.06 ms ± 966 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    选项 2:列表/字典理解

    {a:list(x) for a,x in df.groupby('Name')['Age']}
    # 2.68 ms ± 177 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    输出:

    {'Alex': [10.0],
     'Barbara': [25.0],
     'Bob': [12.0, 72.0],
     'Clarke': [13.0, 13.0],
     'Destiny': [45.0]}
    

    【讨论】:

    • 删除重复项:D
    • 我很欣赏性能测试!这对用户来说非常有用,我经常希望这些信息更多地出现在 SO 帖子中:)
    【解决方案2】:

    defaultdict 可以在这里工作。 drop_duplicates 首先确保仅将唯一值添加到列表中。

    from collections import defaultdict
    
    df = df.drop_duplicates()
    
    d = defaultdict(list)
    for k,v in zip(df.Name, df.Age):
        d[k].append(v)
    #defaultdict(list,
    #            {'Alex': [10.0],
    #             'Barbara': [25.0],
    #             'Bob': [12.0, 72.0],
    #             'Clarke': [13.0],
    #             'Destiny': [45.0]})
    

    它也很快。在有许多组且每个组有几个唯一值的情况下,它的性能将比groupby 好得多。

    import numpy as np
    import pandas as pd
    
    N=10000
    df = pd.DataFrame({'Name': np.arange(0,N,1)//10,
                       'Age': np.arange(0,N,1)%100})
    df = df.drop_duplicates()
    
    def Alollz(df):
        d = defaultdict(list)
        for k,v in zip(df.Name, df.Age):
            d[k].append(v)
        return d
    
    %timeit Alollz(df)
    #3.34 ms ± 7.63 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    %timeit {a:list(x) for a,x in df.groupby('Name')['Age']}
    #113 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

      猜你喜欢
      • 2019-10-31
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 2023-02-14
      • 2018-08-25
      • 2016-09-02
      • 2023-02-23
      相关资源
      最近更新 更多