Столбец со словарем переписать в отдельные столбцы

У меня есть столбец:

all_rel
{'Иван': 0.358, 'Михаил':0.25, 'Илья': 0.456}
{'Иван': 0.698, 'Михаил':0.125, 'Илья': 0.426}
{'Иван': 0.568, 'Михаил':0.145, 'Илья': 0.464}
{'Иван': 0.698, 'Михаил':0.125, 'Илья': 0.426}

Нужно из него переписать данные в несколько столбцов данным образом:

all_rel Иван Михаил Илья
{'Иван': 0.358, 'Михаил':0.25, 'Илья': 0.456} 0.358 0.25 0.456
{'Иван': 0.698, 'Михаил':0.125, 'Илья': 0.426} 0.698 0.125 0.426
{'Иван': 0.568, 'Михаил':0.145, 'Илья': 0.464} 0.568 0.145 0.464
{'Иван': 0.698, 'Михаил':0.125, 'Илья': 0.426} 0.698 0.125 0.426

При этом я не знаю точное значение ключей словаря и их количество, только есть словарь со всеми возможными именами name_dict = {'Иван': 0, 'Михаил':0, 'Илья': 0,'Алексей': 0, 'Андрей': 0}

мой код:


for i in range(srt.shape[0]):
    name_dict.update(ast.literal_eval(srt.all_rel[i]))
    srt.rel_dict[i] = name_dict.copy()

    for key in srt.rel_dict[i]:
        srt[key] = ' '

for i in range(srt.shape[0]):
    for key in srt.rel_dict[i]:
        srt[key][i] = srt.rel_dict[i][key]

srt - имя датафрейма.

Итоговый столбец может содержать и столбцы с другими именами исходного словаря и значением 0 в каждой строке для них.

Есть ли способ это сделать как-то иначе?


Ответы (1 шт):

Автор решения: CrazyElf

На английском SO есть интересный рецепт под ваш случай:

import pandas as pd

df = pd.DataFrame({'all_rel':[
{'Иван': 0.358, 'Михаил':0.25, 'Илья': 0.456},
{'Иван': 0.698, 'Михаил':0.125, 'Илья': 0.426},
{'Иван': 0.568, 'Михаил':0.145, 'Илья': 0.464},
{'Иван': 0.698, 'Михаил':0.125, 'Илья': 0.426},
]})

pd.json_normalize(df['all_rel'])

Вывод:

    Иван    Михаил  Илья
0   0.358   0.250   0.456
1   0.698   0.125   0.426
2   0.568   0.145   0.464
3   0.698   0.125   0.426

В том вопросе по ссылке есть и другие интересные варианты, но этот вроде самый быстрый и простой.

Объединить преобразованные данные с основным датафреймом можно так по индексу:

df = df.drop(columns='all_rel') \
       .join(pd.json_normalize(df['all_rel']))

Или так, ещё короче, как советует уважаемый MaxU:

df = df.join(pd.json_normalize(df.pop('all_rel')))
→ Ссылка