【问题标题】:list of dictionaries into data frame columns字典列表到数据框列
【发布时间】:2021-04-10 18:09:25
【问题描述】:

我在 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'

另外,我也看过那些帖子,但没有用,可能是因为列表结构

How to convert python JSON rows to dataframe columns without looping

Pandas split column of lists into multiple columns

How to split a list of dictionaries into multiple columns keeping the same index?

【问题讨论】:

  • 第一个数据帧的副本中有错别字。 "Info"{"Id":null,... 不是 dict 也不是有效的 JSON。那列datiles 真的包含dicts 吗?我对此表示怀疑,在我看来更像 JSON 字符串(以拼写错误为模)。

标签: python json list


【解决方案1】:

您可以使用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. 第一行执行双重apply:json.loads(您已经想通了)和pd.DataFrame(您也想通了,但这里我们在apply而不是循环中执行) .
  2. 第二行将所有DataFrames 连接到df['datiles'] 中,但使用df 本身的索引作为键。结果是MultiIndex,给定键可能有几行(如果原始datiles JSON 字符串是一个多于1 个元素的列表)。无论如何,我们放弃了第二层。然后join 做它平常的事情(在索引上)。

示例

对于 SO 答案,设置有点冗长(我希望我们有一个 expand 或 fold 宏),所以我将它粘贴到 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

【讨论】:

    猜你喜欢
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 2017-03-01
    • 1970-01-01
    • 2020-07-22
    • 2021-08-14
    相关资源
    最近更新 更多