【问题标题】:How to get a flatten dataframe from lists of dictionaries which contain lists?如何从包含列表的字典列表中获取展平数据框?
【发布时间】:2020-09-21 20:42:23
【问题描述】:

我正在尝试将这种数据结构扁平化为“普通”数据框。

原始数据是一个字典列表,其中包含列表。

数据看起来像这样(可重现的例子):

data = [{'A':[1,2,3,4], 'B':[11,12,13,14]}, {'A':[5,6,7,8], 'B':[15,16,17,18]}]

我想要的输出应该是以下熊猫数据框:

Out[01]: 
   A   B
0  1  11
1  2  12
2  3  13
3  4  14
4  5  15
5  6  16
6  7  17
7  8  18

我怎样才能达到这个结果? 谢谢

【问题讨论】:

    标签: python pandas dictionary flatten


    【解决方案1】:

    为了提高性能,请使用 collections.defaultdictextend

    from collections import defaultdict
    
    d = defaultdict(list)
    for x in data:
        for k, v in x.items():
            d[k].extend(v)
    df = pd.DataFrame(d)
    print (df)
       A   B
    0  1  11
    1  2  12
    2  3  13
    3  4  14
    4  5  15
    5  6  16
    6  7  17
    7  8  18
    

    【讨论】:

    • 巧合的是,我们使用defaultdict 发布了相同的方法。 ;) 但是为什么df.apply(pd.Series.explode) 效率低下?
    • @Ch3steR - 因为 pandas 函数在这里工作得像纯 python 一样慢
    • 不确定我是否理解正确。应该避免df.apply 吗?
    • 如果您可以避免申请,请这样做;其中没有向量化,字典在这种操作中具有优势。 apply 用于所有意图和目的,是 for 循环的包装器。重复应用 series explode 肯定会比dicts慢,
    • @sammywemmy 和 jezrael 谢谢你的解释。从现在开始,我会牢记这一点。
    【解决方案2】:

    您可以使用pd.Series.explode

    data = [{'A':[1,2,3,4], 'B':[11,12,13,14]}, {'A':[5,6,7,8], 'B':[15,16,17,18]}]
    
    df = pd.DataFrame(data).apply(pd.Series.explode).reset_index(drop=True)
    
       A   B
    0  1  11
    1  2  12
    2  3  13
    3  4  14
    4  5  15
    5  6  16
    6  7  17
    7  8  18
    

    或使用collections.defaultdict

    from collections import defaultdict
    new = defaultdict(list)
    
    for d in data:
        for k, v in d.items():
            new[k].extend(v)
    
    df = pd.DataFrame(new)
    
       A   B
    0  1  11
    1  2  12
    2  3  13
    3  4  14
    4  5  15
    5  6  16
    6  7  17
    7  8  18
    

    【讨论】:

      【解决方案3】:

      试试下面的代码:

      
      import pandas as pd
      data = [{'A':[1,2,3,4], 'B':[11,12,13,14]}, {'A':[5,6,7,8], 'B':[15,16,17,18]}]
      
      df = pd.DataFrame(data).apply(pd.Series.explode).reset_index(drop=True)
      
      print(df)
      

      【讨论】:

        【解决方案4】:

        您可以简单地生成每个 DataFrame 并将它们全部连接起来:

        import pandas as pd
        
        data = [{'A':[1,2,3,4], 'B':[11,12,13,14]}, {'A':[5,6,7,8], 'B':[15,16,17,18]}]
        
        df = pd.concat((pd.DataFrame(elm) for elm in data), ignore_index=True)
        print(df)
        
        
           A   B
        0  1  11
        1  2  12
        2  3  13
        3  4  14
        4  5  15
        5  6  16
        6  7  17
        7  8  18
        

        【讨论】:

        • 也可以df = pd.concat(map(pd.DataFrame, data),ignore_index=True).
        猜你喜欢
        • 1970-01-01
        • 2023-02-20
        • 2019-01-11
        • 2016-03-16
        • 2021-08-19
        • 1970-01-01
        • 2019-01-10
        • 2021-08-22
        • 1970-01-01
        相关资源
        最近更新 更多