#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())