【问题标题】:How to transform a list of dictionaries, containing nested lists into a pandas df如何将包含嵌套列表的字典列表转换为 pandas df
【发布时间】:2021-04-27 04:16:41
【问题描述】:

我有一个字典列表:

list_of_dicts = [{'name': 'a', 'counts': [{'dog': 2}]}, 
          {'name': 'b', 'counts': [{'cat': 1}, {'capibara': 5}, {'whale': 10}]}, 
          {'name': 'c', 'counts': [{'horse':1}, {'cat': 1}]]

我想将其转换为 pandas 数据框,如下所示:

Name Animal Frequency
a dog 2
b cat 1
b capibara 5
b whale 10
c horse 1
c cat 1

在当前代码中,我尝试对其进行规范化:

from pandas import json_normalize
df = json_normalize(list_of_dicts, 'counts')

但我认为我走错了方向。另外,如果我做一个简单的 df = pd.DataFrame(list_of_dicts) ,它会导致每个 dicts 列表都是一个单行值,这是不希望的。

【问题讨论】:

    标签: python pandas list dictionary json-normalize


    【解决方案1】:
    • 必须使用pandas.json_normalizerecord_pathmeta 参数。
    • 这些列将是动物,它们被堆叠成一列。
    import pandas as pd
    
    # test data
    list_of_dicts = [{'name': 'a', 'counts': [{'dog': 2}]}, {'name': 'b', 'counts': [{'cat': 1}, {'capibara': 5}, {'whale': 10}]}, {'name': 'c', 'counts': [{'horse':1}, {'cat': 1}]}]
    
    # load and transform the dataframe
    pd.json_normalize(list_of_dicts, 'counts', 'name').set_index('name').stack().reset_index().rename(columns={'level_1': 'Animal', 0: 'Frequency'})
    
    # display(df)
      name    Animal  Frequency
    0    a       dog        2.0
    1    b       cat        1.0
    2    b  capibara        5.0
    3    b     whale       10.0
    4    c     horse        1.0
    5    c       cat        1.0
    

    【讨论】:

    • 不错的解决方案,我必须继续研究这些不错的 pandas 方法 :)
    • @blah 很高兴这对你有用。是的,有一些方法可以转换数据帧。
    【解决方案2】:

    试试json_normalizemelt

    (pd.json_normalize(list_of_dicts, record_path='counts', meta='name')
       .melt('name', var_name='Animal', value_name='Frequency')
       .dropna()
    )
    

    输出:

       name    Animal  Frequency
    0     a       dog        2.0
    7     b       cat        1.0
    11    c       cat        1.0
    14    b  capibara        5.0
    21    b     whale       10.0
    28    c     horse        1.0
    

    【讨论】:

      【解决方案3】:

      试试这个?

      >>> pd.json_normalize(list_of_dicts, 'counts').melt().dropna()
      

      【讨论】:

      • 这不会有'name'
      • 啊,太好了 :-) 我忘记了...反正我看到其他人已经回答了
      【解决方案4】:

      您也可以将df.explodedf.apply 一起使用:

      In [50]: df = pd.DataFrame(list_of_dicts).explode('counts')
      In [74]: df.counts = df.counts.apply(lambda x: list(x.items())[0])
      
      In [77]: df[['Animal', 'Frequency']] = pd.DataFrame(df['counts'].tolist(), index=df.index)
      
      In [79]: df.drop('counts', 1, inplace=True)
      
      In [80]: df
      Out[80]: 
        name    Animal  Frequency
      0    a       dog          2
      1    b       cat          1
      1    b  capibara          5
      1    b     whale         10
      2    c     horse          1
      2    c       cat          1
      

      【讨论】:

        猜你喜欢
        • 2020-09-11
        • 2021-08-10
        • 2019-12-31
        • 2022-10-13
        • 2018-10-26
        • 1970-01-01
        • 2019-05-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多