Pandas dataframe to dict of dict
Учитывая следующий кадр данных pandas:
ColA ColB ColC
0 a1 t 1
1 a2 t 2
2 a3 d 3
3 a4 d 4
Я хочу получить словарь словаря.
Но мне удалось создать только следующее:
d = {t : [1, 2], d : [3, 4]}
от:
d = {k: list(v) for k,v in duplicated.groupby("ColB")["ColC"]}
Как я мог получить диктовку dict:
dd = {t : {a1:1, a2:2}, d : {a3:3, a4:4}}
Ответы
Ответ 1
Вы можете сделать это с помощью groupby
+ apply
шаг заранее.
dd = df.set_index('ColA').groupby('ColB').apply(
lambda x: x.ColC.to_dict()
).to_dict()
Или, с пониманием дикта:
dd = {k : g.ColC.to_dict() for k, g in df.set_index('ColA').groupby('ColB')}
print(dd)
{'d': {'a3': 3, 'a4': 4}, 't': {'a1': 1, 'a2': 2}}
Ответ 2
Цель этого ответа - показать, что есть прямой способ сделать это с помощью простой итерации и инструментов из стандартной библиотеки.
Часто мы выполняем много преобразований в Pandas DataFrame, где каждое преобразование вызывает конструкцию нового объекта Pandas. Время от времени это может быть интуитивной прогрессией и иметь прекрасный смысл. Однако есть моменты, когда мы забываем, что мы можем использовать более простые инструменты. Я считаю, что это один из тех времен. Мой ответ по-прежнему использует Pandas, поскольку я использую метод itertuples
.
from collections import defaultdict
d = defaultdict(dict)
for a, b, c in df.itertuples(index=False):
d[b][a] = c
d = dict(d)
d
{'t': {'a1': 1, 'a2': 2}, 'd': {'a3': 3, 'a4': 4}}
Небольшая альтернатива. Поскольку кортежи, которые мы итерируем, называются кортежами, мы можем получить доступ к каждому элементу по имени столбца, который он представляет.
from collections import defaultdict
d = defaultdict(dict)
for t in df.itertuples():
d[t.ColB][t.ColA] = t.ColC
d = dict(d)
d
{'t': {'a1': 1, 'a2': 2}, 'd': {'a3': 3, 'a4': 4}}