Фрейм данных Pandas — список dicts для разделения столбцов

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

У меня есть фрейм данных, df, в котором есть столбец, представляющий собой список словарей:

 index action
0     [{'action_type': 'landing_page_view', 'value': '1'}, {'action_type': 'link_click', 'value': '1'}{'action_type': 'page_engagement', 'value': '1'}, {'action_type': 'post_engagement', 'value': '1'}]
1     [{'action_type': 'landing_page_view', 'value': '1'}, {'action_type': 'link_click', 'value': '1'}, {'action_type': 'page_engagement', 'value': '1'}, {'action_type': 'post_engagement', 'value': '1'}]
2     [{'action_type': 'video_view', 'value': '23'}, {'action_type': 'page_engagement', 'value': '23'}, {'action_type': 'post_engagement', 'value': '23'}]
 

Я хочу иметь возможность извлекать значение из каждого словаря и приписывать его собственному столбцу, например

 index action_landing_page_view action_link_click action_page_engagement action_post_engagement action_video_view
0     1                        1                 1                      1                      0
1     1                        1                 1                      1                      0
2     0                        0                 23                     23                     23

 

Я попробовал df.apply(pd.Series) , который разбивает dicts на отдельные столбцы, но без заголовков столбцов.

Словари, которые находятся в моем исходном фрейме данных, не следуют одному и тому же порядку. например, первый dict для строки 1 начинается с action_type «landing_page_view», тогда как строка 3 начинается с «video_view».

Можно ли приписывать значения разным столбцам на основе action_type в словаре?

Комментарии:

1. как вы создали этот фрейм данных? я думаю, что подобные задачи лучше всего выполнять при установке фрейма данных, а не после факта

2. выполнен вызов api маркетинга facebook, который возвращает некоторый json. затем я использовал json_normalize для создания этого фрейма данных.

3. Тогда я рекомендую опубликовать JSON

Ответ №1:

Мы можем решить эту проблему, используя понимание списка:

 pd.DataFrame(
    [{e['action_type']: e['value']
      for e in l}
     for l in list(df['action'])]
).fillna(0)
 

Обратите внимание, что я реконструировал ваш фрейм данных следующим образом:

 import pandas as pd

df = pd.DataFrame([[
    [
        {'action_type': 'landing_page_view', 'value': '1'},
        {'action_type': 'link_click', 'value': '1'},
        {'action_type': 'page_engagement', 'value': '1'},
        {'action_type': 'post_engagement', 'value': '1'},
    ],
    [
        {'action_type': 'landing_page_view', 'value': '1'},
        {'action_type': 'link_click', 'value': '1'},
        {'action_type': 'page_engagement', 'value': '1'},
        {'action_type': 'post_engagement', 'value': '1'},
    ],
    [
        {'action_type': 'video_view', 'value': '23'},
        {'action_type': 'page_engagement', 'value': '23'},
        {'action_type': 'post_engagement', 'value': '23'},
    ]]]
)
df = df.transpose()
df = df[0].rename('action')
df = pd.DataFrame(df)
 

Ответ №2:

Сначала вы должны извлечь ключевые значения для имени столбца и значений столбца, а затем создать фрейм данных на их основе. (Я думаю, что с самого начала не имеет смысла иметь такие словари. Имеет смысл иметь их так : {'landing_page_view': 1} )

 index_action_extracted = [{} for i in range(len(index_action))]

for i in range(len(index_action)):
    list_ = index_action[i]
    for dict_ in list_:
        column_name = dict_['action_type']
        column_value = dict_['value']
        index_action_extracted[i].update({column_name: column_value})

df = pd.DataFrame(index_action_extracted).fillna(0)

 

В index_action_extracted мы удаляем избыточные ключи 'action_type' 'value' и создаем словарь без этих ключей.

Ответ №3:

Я возвращаю список элементов словаря, а затем сопоставляю элементы словаря с фреймом данных, а затем переношу фрейм данных

  df = pd.DataFrame([
    [
    {'action_type': 'landing_page_view', 'value': '1'},
    {'action_type': 'link_click', 'value': '1'},
    {'action_type': 'page_engagement', 'value': '1'},
    {'action_type': 'post_engagement', 'value': '1'},
],
[
    {'action_type': 'landing_page_view', 'value': '1'},
    {'action_type': 'link_click', 'value': '1'},
    {'action_type': 'page_engagement', 'value': '1'},
    {'action_type': 'post_engagement', 'value': '1'},
],
[
    {'action_type': 'video_view', 'value': '23'},
    {'action_type': 'page_engagement', 'value': '23'},
    {'action_type': 'post_engagement', 'value': '23'},
]
])

df2=pd.DataFrame(columns=['action_type','value'])
for key,dictList in df.iterrows():
    for key, dictAction in dictList.items():  #returns tuple (index, dict)
    #print(dictAction)
        if (dictAction is None)==False:
        
            keys=dictAction.keys()
            index=len(df2)
            for key in keys:
               value=dictAction[key]
               df2.loc[index,key]=value

df2=df2.T
print(df2.head())