【问题标题】:Extract nested dictionary from Pandas columns从 Pandas 列中提取嵌套字典
【发布时间】:2020-01-21 19:38:43
【问题描述】:

我尝试从我的 pandas 数据框中的嵌套字典创建一个数据框,但我无法让它工作...

我的数据框:

    created_at                  selected
    2019-08-13T12:24:53+00:00   {"982813":false,"1786112":true,"3002218":false}
    2019-08-31T13:47:51+00:00   {"309279":true,"1903384":false}
        ...

并且我想创建一个新的 df,其所选列数据的格式如下:

        created_at                  ID            Value
        2019-08-13T12:24:53+00:00   982813        false    
        2019-08-13T12:24:53+00:00   1786112       true
        2019-08-13T12:24:53+00:00   3002218       false
        2019-08-31T13:47:51+00:00   309279        true
        2019-08-31T13:47:51+00:00   1903384       false
        ...

我一直在尝试使用 explode() 和 json_normalize() 但没有成功,所以我决定使用 pd.DataFrame.from_dict() 和如下的 for 循环,但我遇到了错误。

x = {}
for row in df.selected:
    pd.DataFrame.from_dict(row, orient='index')

但我收到以下错误:

AttributeError: 'str' 对象没有属性 'values'

我仍然是 python 的初学者,所以如果有人作为一个想法/解释我全神贯注。

【问题讨论】:

  • 这是因为每个row 都是一个字符串,而不是dict。您的预期输出是什么?
  • 我的目标是取出字典并创建一个新的 df。使用以下代码,我只想输出数据以使用 id 作为索引和列中的 True/False。像这样:python for row in df.selected: x[row] = pd.DataFrame.from_dict(row, orient='index') final = pd.concat(x.values()) print(final) Index Value 982813 false 1786112 true 3002218 false 309279 true 1903384 false ...

标签: python pandas


【解决方案1】:

这是一个向您展示这个想法的微型示例。如果您的音量很大,则不建议这样做:

import pandas as pd

df = pd.DataFrame([[1, {'abc':11}], [2, {'def':22, 'ghi':33}]], columns=['id', 'dct'])

lst = []

for index, row in df.iterrows():
    for key, value in row['dct'].items():
        lst.append([row['id'], key, value])


new = pd.DataFrame(lst, columns=['id', 'string', 'value'])

print(new)

【讨论】:

    【解决方案2】:

    在您的情况下,您可以在 0.25.0 之后在熊猫中使用 explode

    df.BB=df.BB.map(lambda x : list(x.items()))
    s=df.explode('BB')
    pd.concat([s,pd.DataFrame(s.BB.tolist(),index=s.index)],axis=1)
    Out[93]: 
       CC      BB  0  1
    0   1  (1, 2)  1  2
    0   1  (2, 1)  2  1
    1   2  (2, 2)  2  2
    1   2  (8, 3)  8  3
    1   2  (4, 5)  4  5
    

    数据

    df= pd.DataFrame({'CC':[1,2],'BB':[{1:2,2:1},{2:2,8:3,4:5}]})
    

    【讨论】:

      【解决方案3】:

      您想使用.apply(pd.Series)stack(),然后重命名您的列:

      df.set_index('created_at')['selected'].apply(pd.Series).stack().reset_index().rename(columns={'level_1':'ID',0:'Value'})
      
                        created_at       ID  Value
      0  2019-08-13T12:24:53+00:00   982813  False
      1  2019-08-13T12:24:53+00:00  1786112   True
      2  2019-08-13T12:24:53+00:00  3002218  False
      3  2019-08-31T13:47:51+00:00   309279   True
      4  2019-08-31T13:47:51+00:00  1903384  False
      

      顺便说一句,为了将来参考,您可以通过提供代码来复制您的起点来更快地获得答案。大部分时间我都在想这个:

      df = pd.DataFrame({"created_at": ['2019-08-13T12:24:53+00:00', '2019-08-31T13:47:51+00:00'], "selected": [{"982813":False,"1786112":True,"3002218":False}, {"309279":True,"1903384":False}]})
      

      【讨论】:

        猜你喜欢
        • 2021-03-01
        • 1970-01-01
        • 2021-11-09
        • 2021-06-02
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        相关资源
        最近更新 更多