数据框的一列是字典列表,我需要将其解析为新的单词

时间:2019-05-11 14:58:35

标签: python pandas

我有一个数据框,其中有一列称为动作,并带有字典列表。格式为{source:int,action:string},我需要将其解析为新的列,但是每个操作单元格中的记录数是可变的。

数据如下:

|Id  |action                                                     |
|1   |[{"E": 4, "action": "views"}, {"A": 58, "action": "views"}]|
|2   |[{"A": 74, "action": "clicks"}]                            |

我希望它看起来像这样:

|Id|Source|Value|Action|
|1 |E     |4    |views |
|1 |A     |58   |views |
|2 |A     |74   |clicks|

“操作”列中的词典数量最多为10

我已经尝试了几种解决方案,例如pandas DataFrame: normalize one JSON column and merge with other columns

但是它告诉我第一个解决方案没有正确调用DataFrame,而第二个解决方案的str没有属性值。甚至除此之外,这并不是我需要的解决方案,因为我需要重命名列源并将A / E / etc值放入其中。

3 个答案:

答案 0 :(得分:2)

我将使用unnesting

yourdf=unnesting(df,['action']).reset_index(drop=True)
s=pd.DataFrame(yourdf.action.tolist()).reset_index().melt(['action','index']).dropna().set_index('index')

yourdf=pd.concat([yourdf,s],axis = 1)
yourdf
                          action  ID  action variable  value
0    {'E': 4, 'action': 'views'}   1   views        E    4.0
1   {'A': 58, 'action': 'views'}   1   views        A   58.0
2  {'A': 74, 'action': 'clicks'}   2  clicks        A   74.0

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([
        pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')

答案 1 :(得分:1)

只需使用列表理解来重建您的DataFrame数据:

更新:所以action列是一个 string 字段,而不是Python数据结构。您可以使用 json.loads 对其进行预处理,这在从字符串中解析数据结构方面不易出错。

import json

# original dataframe
df = pd.DataFrame([
        (1, '[{"E": 4, "action": "views"}, {"A": 58, "action": "views"}]') 
      , (2, '[{"A": 74, "action": "clicks"}]') 
    ], 
    columns=['Id', 'action']
)

# new dataframe
df_new = pd.DataFrame(
    [ (id, k, v, i['action']) for id,act in zip(df.Id, df.action.apply(json.loads))
                              for i in act
                              for k,v in i.items() if k != 'action' 
    ],
    columns=['Id', 'Source', 'Value', 'Action']
)

print(new_df)
#   Id Source  Value  Action
#0   1      E      4   views
#1   1      A     58   views
#2   2      A     74  clicks

答案 2 :(得分:0)

我确实做了很长的路要走,但它可以为您提供所需的输出。我只是在数据框的列内嵌套字典。这仅在字典仅采用您在示例数据框中显示的格式时才有效。

import pandas as pd

df = pd.DataFrame({'id': [1,2],
                   'action': [[{"E": 4, "action": "views"}, 
                               {"A": 58, "action": "views"}], 
                              [{"A": 74, "action": "clicks"}]]}
                 )

df_list = []
cols = ['id', 'source', 'value', 'action']
for x in df.index:
    for actions in df.loc[x, 'action']:
        row = []
        row.append(df.loc[x,'id'])
        for k,v in actions.items():
            if k == 'action':
                row.append(v)
            else:
                row.append(k)
                row.append(v)    
        df_list.append(row)
test = pd.DataFrame(df_list, columns=cols)

哪个给出此输出

   id source  value  action
0   1      E      4   views
1   1      A     58   views
2   2      A     74  clicks