从熊猫列中提取嵌套字典

时间:2019-09-20 18:30:09

标签: python 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的初学者,所以如果有人作为想法/解释我很耳熟。

3 个答案:

答案 0 :(得分:0)

这是一个微型示例,向您展示这个想法。如果体积较大,不建议使用

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)

答案 1 :(得分:0)

对于您而言,您可以在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}]})

答案 2 :(得分:0)

您要使用.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}]})