【问题标题】:parsing a list of dictionaries in a pandas data frame rows解析熊猫数据框行中的字典列表
【发布时间】:2020-01-15 07:24:16
【问题描述】:

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

这是数据框:

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...

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

更新: 解决方案尝试过

【问题讨论】:

    标签: python-3.x pandas dataframe dictionary


    【解决方案1】:

    你必须首先使用 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)
    
    

    【讨论】:

    • event_params 包含 'list' 然后我们可以访问 'key'
    • 你可以试试这个。爆炸为您完成了这一步。它在“event_params”中创建了许多只有字典的行。
    • 我确实尝试过,它给出了以下错误:TypeError: string indices must be integers
    • 我的工作非常好。你能告诉我你在哪一行收到错误吗?
    • 在第一个循环中,因为它是一个字典列表,所以它无法访问它
    【解决方案2】:

    使用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
    

    【讨论】:

    • AttributeError: 'str' 对象没有属性 'values',最初我使用 ast.literal_eval 将字符串转换为列表。然后我必须迭代列出然后访问字典值
    • 是的,我忘了添加那部分。在literal_eval之后试试?
    • 当我在循环中使用 literal_eval 时,.values() 不起作用,因为它会弹出列表
    猜你喜欢
    • 2020-07-09
    • 2020-07-22
    • 2015-06-02
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 2019-08-01
    相关资源
    最近更新 更多