首页 > 解决方案 > 字典列表到数据框列中

问题描述

我在 a 中有一个DataFrame包含 JSON 字符串的列,每个字符串代表一个字典列表:

    id Number  Type  Class Name                                                                                                                                                                                                                                datiles
0  292      C     1      2    A  [{"did":{"id":"3","num":1},"NId":"a1,b1,c1","Att":null,"isnull":false,"number":"M90","label":[{"title":"Dear","Info":{"Id":null,"id2":2,"Name":"x"}},{"title":"Dear","Info":{"Id":null,"id2":2,"Name":"x"}}],"codes":[],"rule":null}]
1  293      C     1      2    A  [{"did":{"id":"3","num":1},"NId":"a1,b1,c1","Att":null,"isnull":false,"number":"M90","label":[{"title":"Dear","Info":{"Id":null,"id2":2,"Name":"x"}},{"title":"Dear","Info":{"Id":null,"id2":2,"Name":"x"}}],"codes":[],"rule":null}]

我想将 datiles 列中的每一行转换为行和列,并将它们与原始数据框连接起来,如下面的示例所示:

       id     Number       Type     Class      Name            did                NId        Att  ..... .... label ........
      0292           C          1          2        A     {"id":"3","num":1}    a1,b1,c1    null    [{"title":"Dear","Info"{"Id":null,"id2":2,"Name":"x"}},{"title":"Dear","Info":{"Id":null,"id2":2,"Name":"x"}}]

我已经根据需要完成了此操作,但我不知道如何将其与原始数据框连接起来,因为它们之间没有密钥:

df['datiles']=data['datiles'].apply(json.loads)

df2 = pd.DataFrame([])

for x in df['datiles'].values.tolist():
    df2 = df2 .append(pd.DataFrame(x))
display(df2)

如何拆分列并同时加入?我曾尝试使用 json_normalize 但我收到此错误

AttributeError: 'list' object has no attribute 'values'

另外,我看过那些帖子但不起作用,可能是因为列表结构

如何在不循环的情况下将python JSON行转换为数据框列

Pandas 将列表列拆分为多列

如何将字典列表拆分为保持相同索引的多个列?

标签: pythonjsonlist

解决方案


您可以使用您的索引df并将其明确设置为您的新DataFrame加入,如下所示:

df['datiles'] = df['datiles'].apply(json.loads).apply(pd.DataFrame)
out = df.drop('datiles', axis=1).join(
    pd.concat(df['datiles'].values, keys=df.index).droplevel(1))

解释

  1. 第一行做了一个 double apply: json.loads(正如你所想的那样) 和pd.DataFrame(你也已经想出来了,但在这里我们用一个apply而不是循环来做)。
  2. 第二行连接所有DataFrames内部df['datiles']的,但使用df自身的索引作为键。结果是 a MultiIndex,给定键可能有几行(如果原始datilesJSON 字符串是超过 1 个元素的列表)。无论如何,我们放弃了第二个级别。然后join做它通常的事情(在索引上)。

例子

对于 SO 答案,设置有点冗长(我希望我们有一个expandorfold宏),所以我将它粘贴到pastebin中。

重点是,第一个datiles是两个元素的 JSON 列表,只是为了练习上面的逻辑。除此之外,它与OP的内容相同。

输出

    id Number  Type  Class Name                    did       NId   Att  \
0  292      C     1      2    A  {'id': '1', 'num': 1}  a1,b1,c1  None   
0  292      C     1      2    A  {'id': '2', 'num': 1}  a1,b1,c1  None   
1  293      C     1      2    A  {'id': '3', 'num': 1}  a1,b1,c1  None   

   isnull number                                              label codes  \
0   False    M90  [{'title': 'Dear', 'Info': {'Id': None, 'id2':...    []   
0   False    M90  [{'title': 'Dear', 'Info': {'Id': None, 'id2':...    []   
1   False    M90  [{'title': 'Dear', 'Info': {'Id': None, 'id2':...    []   

   rule  
0  None  
0  None  
1  None

推荐阅读