【问题标题】:How to split a list of dictionaries into multiple columns keeping the same index?如何将字典列表拆分为保持相同索引的多个列?
【发布时间】:2019-12-27 11:24:49
【问题描述】:

我有一个数据框,它有一个时间戳和一个包含字典列表的列作为索引:

    index                   var_A

    2019-08-21 09:05:49    [{"Date1": "Aug 21, 2017 9:09:51 AM","Date2": "Aug 21, 2017 9:09:54 AM","Id": "d5e665e5","num_ins": 108,"num_del": 0, "time": 356} , {"Date1": "Aug 21, 2017 9:09:57 AM","Date2": "Aug 21, 2017 9:09:59 AM","Id": "d5e665e5","num_ins": 218,"num_del": 5, "time": 166}]
    2019-08-21 09:05:59    [{"Date1": "Aug 21, 2017 9:10:01 AM","Date2": "Aug 21, 2017 9:11:54 AM","Id": "d5e665e5","num_ins": 348,"num_del": 72, "time": 3356} , {"Date1": "Aug 21, 2017 9:19:57 AM","Date2": "Aug 21, 2017 9:19:59 AM","Id": "d5e665e5","num_ins": 69,"num_del": 5, "time": 125}, {"Date1": "Aug 21, 2017 9:20:01 AM","Date2": "Aug 21, 2017 9:21:54 AM","Id": "f9e775f9","num_ins": 470,"num_del": 0, "time": 290} ]
    2019-08-21 09:06:04    []

我希望实现的是这样的数据框:

    index              Date1                      Date2                    Id      num_ins       num_del    time
2019-08-21 09:05:49   Aug 21, 2017 9:09:51AM   Aug 21, 2017 9:09:54AM   d5e665e5      0           108        356
2019-08-21 09:05:49   Aug 21, 2017 9:09:57AM   Aug 21, 2017 9:09:59AM   d5e665e5      218           5        166
2019-08-21 09:05:59   Aug 21, 2017 9:10:01AM   Aug 21, 2017 9:11:54AM   d5e665e5      348          72       3356
2019-08-21 09:05:59   Aug 21, 2017 9:19:57AM   Aug 21, 2017 9:19:59AM   d5e665e5      69            5        125
2019-08-21 09:05:59   Aug 21, 2017 9:20:01AM   Aug 21, 2017 9:21:54AM   f9e775f9      470           0        290
2019-08-21 09:06:04     NAN                         NAN                    NAN        NAN         NAN        NAN

【问题讨论】:

    标签: python pandas list dictionary


    【解决方案1】:

    enumerate循环每个值,因为重复的inex值并创建DataFrames,然后为空列表创建DataFrame并最后concat一起:

    import ast
    
    out = {}
    for i, (k, v) in enumerate(df['var_A'].items()):
        df = pd.DataFrame(v)
        if df.empty:
            out[(i, k)] = pd.DataFrame(index=[0], columns=['Id'])
        else:
            out[(i, k)] = df
    
    df = pd.concat(out, sort=True).reset_index(level=[0,2], drop=True)
    print (df)
                                           Date1                    Date2  \
    2019-08-21 09:05:49  Aug 21, 2017 9:09:51 AM  Aug 21, 2017 9:09:54 AM   
    2019-08-21 09:05:49  Aug 21, 2017 9:09:57 AM  Aug 21, 2017 9:09:59 AM   
    2019-08-21 09:05:59  Aug 21, 2017 9:10:01 AM  Aug 21, 2017 9:11:54 AM   
    2019-08-21 09:05:59  Aug 21, 2017 9:19:57 AM  Aug 21, 2017 9:19:59 AM   
    2019-08-21 09:05:59  Aug 21, 2017 9:20:01 AM  Aug 21, 2017 9:21:54 AM   
    2019-08-21 09:05:59                      NaN                      NaN   
    
                               Id  num_del  num_ins    time  
    2019-08-21 09:05:49  d5e665e5      0.0    108.0   356.0  
    2019-08-21 09:05:49  d5e665e5      5.0    218.0   166.0  
    2019-08-21 09:05:59  d5e665e5     72.0    348.0  3356.0  
    2019-08-21 09:05:59  d5e665e5      5.0     69.0   125.0  
    2019-08-21 09:05:59  f9e775f9      0.0    470.0   290.0  
    2019-08-21 09:05:59       NaN      NaN      NaN     NaN  
    

    【讨论】:

    • 感谢您的回复!我仍然收到错误消息。实际上,我的帖子中有错字。我的原始索引是唯一的。不知道会不会有影响。但是错误说:格式错误的节点或字符串:
    • @jessirocha - print (type(df.loc[0, 'var_A'])) 是什么?
    • @jessirocha - 如果返回列表,则将 df = pd.DataFrame(ast.literal_eval(v)) 更改为 df = pd.DataFrame(v)
    • 我无法打印它:无法使用 的这些索引器 [0] 对 进行索引索引
    • 有效!之前它一定是一个错误。它返回了一个列表,我按照建议替换为 df = pd.DataFrame(v) 。非常感谢您的帮助!
    【解决方案2】:

    您可以使用pandas 函数stackconcat 来执行此操作。

    1. 首先使用stack取消列表列var_A
    2. 然后使用concat 取消嵌套字典并将其放入单独的列中

    您可以使用以下代码来执行相同的操作。假设你的字典是 df。

    不列出:

    df = df.apply(lambda x: x.apply(pd.Series).stack()).reset_index().drop('level_1', 1)
    

    不嵌套:

    df = pd.concat([df.drop('var_A', axis=1), df['var_A'].apply(pd.Series)], axis=1).drop(0,1)
    

    【讨论】:

      猜你喜欢
      • 2011-05-04
      • 2020-04-23
      • 2021-10-23
      • 1970-01-01
      • 2010-12-19
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 2022-12-20
      相关资源
      最近更新 更多