解析熊猫数据框行中的词典列表

时间:2020-01-15 07:24:16

标签: python-3.x pandas dataframe dictionary

我在pandas dataframe列中有一个列表字典。我想解析它并从中创建新行,即使其他列值重复。

以下是数据框:

event_date  event_timestamp event_name  event_params
20191118    1.57401E+15 user_engagement [{'key': 'firebase_event_origin', 'value': {'string_value': 'auto', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_number', 'value': {'string_value': None, 'int_value': 5, 'float_value': None, 'double_value': None}}, {'key': 'engagement_time_msec', 'value': {'string_value': None, 'int_value': 17167, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_id', 'value': {'string_value': None, 'int_value': 9065232440298470924, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_id', 'value': {'string_value': None, 'int_value': 1574005142, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_class', 'value': {'string_value': 'SplashActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'engaged_session_event', 'value': {'string_value': None, 'int_value': 1, 'float_value': None, 'double_value': None}}]
20191119    1.57401E+15 screen_view [{'key': 'firebase_previous_id', 'value': {'string_value': None, 'int_value': 9065232440298470924, 'float_value': None, 'double_value': None}}, {'key': 'firebase_event_origin', 'value': {'string_value': 'auto', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_number', 'value': {'string_value': None, 'int_value': 5, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_id', 'value': {'string_value': None, 'int_value': 9065232440298470925, 'float_value': None, 'double_value': None}}, {'key': 'firebase_previous_class', 'value': {'string_value': 'SplashActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_id', 'value': {'string_value': None, 'int_value': 1574005142, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_class', 'value': {'string_value': 'AuthenticationActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'engaged_session_event', 'value': {'string_value': None, 'int_value': 1, 'float_value': None, 'double_value': None}}]
20191120    1.57401E+15 user_engagement [{'key': 'firebase_event_origin', 'value': {'string_value': 'auto', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_number', 'value': {'string_value': None, 'int_value': 5, 'float_value': None, 'double_value': None}}, {'key': 'engagement_time_msec', 'value': {'string_value': None, 'int_value': 13271, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_id', 'value': {'string_value': None, 'int_value': 9065232440298470925, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_id', 'value': {'string_value': None, 'int_value': 1574005142, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_class', 'value': {'string_value': 'AuthenticationActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'engaged_session_event', 'value': {'string_value': None, 'int_value': 1, 'float_value': None, 'double_value': None}}]

这就是我想要的

event_date  event_timestamp event_name      key                    value
20191118    1.57401E+15     user_engagement firebase_event_origin   auto
20191118    1.57401E+15     user_engagement ga_session_number        5
20191118    1.57401E+15     user_engagement engagement_time_msec    17167
20191119    1.57401E+15     screen_view     firebase_previous_id    9.06523E+18
20191119    1.57401E+15     screen_view     engaged_session_event    1

这是我尝试过的:

pd.DataFrame(data['event_params'].apply(ast.literal_eval).values.tolist()) \
        .stack() \
        .reset_index(level=0,drop=True) \
        .reset_index()

它给了我以下输出:

index     0
0        {'key': 'firebase_event_origin', 'value': {'st...
1       {'key': 'ga_session_number', 'value': {'string...
2       {'key': 'engagement_time_msec', 'value': {'str...

如何解析更多填充的列“键”和“值”。另外,使其他列值重复。请帮助我。

更新: 解决方案尝试

Solution tried as per @bharath

2 个答案:

答案 0 :(得分:2)

您必须首先使用pandas.series.explode()爆炸数据框。 然后编写几个for循环以获得预期的结果。 这是答案。

import pandas as pd

d = {'event_date': [1, 2], 'event_name': [3, 4] ,'event_params': [[{'key': 'firebase_event_origin', 'value': {'string_value': 'auto', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_number', 'value': {'string_value': None, 'int_value': 5, 'float_value': None, 'double_value': None}}, {'key': 'engagement_time_msec', 'value': {'string_value': None, 'int_value': 17167, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_id', 'value': {'string_value': None, 'int_value': 9065232440298470924, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_id', 'value': {'string_value': None, 'int_value': 1574005142, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_class', 'value': {'string_value': 'SplashActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'engaged_session_event', 'value': {'string_value': None, 'int_value': 1, 'float_value': None, 'double_value': None}}], [{'key': 'firebase_previous_id', 'value': {'string_value': None, 'int_value': 9065232440298470924, 'float_value': None, 'double_value': None}}, {'key': 'firebase_event_origin', 'value': {'string_value': 'auto', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_number', 'value': {'string_value': None, 'int_value': 5, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_id', 'value': {'string_value': None, 'int_value': 9065232440298470925, 'float_value': None, 'double_value': None}}, {'key': 'firebase_previous_class', 'value': {'string_value': 'SplashActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'ga_session_id', 'value': {'string_value': None, 'int_value': 1574005142, 'float_value': None, 'double_value': None}}, {'key': 'firebase_screen_class', 'value': {'string_value': 'AuthenticationActivity', 'int_value': None, 'float_value': None, 'double_value': None}}, {'key': 'engaged_session_event', 'value': {'string_value': None, 'int_value': 1, 'float_value': None, 'double_value': None}}]]}


df = pd.DataFrame(d)

df = df.explode('event_params').reset_index(drop = True)

df['key'] = None

for i in range(len(df)):
    df.loc[i, 'key'] = df.loc[i, 'event_params']['key']

df['value'] = None

for i in range(len(df)):
    for k in df.loc[i, 'event_params']['value']:
        if df.loc[i, 'event_params']['value'][k]!=None:
            df.loc[i, 'value'] = df.loc[i, 'event_params']['value'][k]


df.drop(columns = 'event_params', inplace = True)

答案 1 :(得分:0)

使用pandas.DataFrame.explode

new_df = df.explode('event_params')
tmp = pd.DataFrame(list(new_df.pop('event_params')))
new_df['value'] = tmp['value'].apply(lambda x:next(i for i in x.values() if i is not None ))

输出:

   event_date  event_timestamp       event_name  value
0    20191118     1.574010e+15  user_engagement   auto
0    20191118     1.574010e+15  user_engagement   auto
0    20191118     1.574010e+15  user_engagement   auto
0    20191118     1.574010e+15  user_engagement   auto
0    20191118     1.574010e+15  user_engagement   auto
0    20191118     1.574010e+15  user_engagement   auto
0    20191118     1.574010e+15  user_engagement   auto
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
1    20191119     1.574010e+15      screen_view      5
2    20191120     1.574010e+15  user_engagement  17167
2    20191120     1.574010e+15  user_engagement  17167
2    20191120     1.574010e+15  user_engagement  17167
2    20191120     1.574010e+15  user_engagement  17167
2    20191120     1.574010e+15  user_engagement  17167
2    20191120     1.574010e+15  user_engagement  17167
2    20191120     1.574010e+15  user_engagement  17167