groupby
+ agg
+ to_dict
df.groupby(["Col1", "Col2"])[["Key", "Value"]].agg(list).transform(lambda x: dict(zip(*x)),1).reset_index(name='kvpairs').to_dict('records')
[{'Col1': 101, 'Col2': 'a', 'kvpairs': {'f1': 'abc', 'f2': 'def'}},
{'Col1': 102, 'Col2': 'a', 'kvpairs': {'f2': 'xyz', 'f3': 'fgh'}},
{'Col1': 103, 'Col2': 'b', 'kvpairs': {'f1': 'rst'}}]
Если, конечно, df
- это
z = io.StringIO("""Col1 Col2 Key Value
101 a f1 abc
101 a f2 def
102 a f2 xyz
102 a f3 fgh
103 b f1 rst""")
df = pd.read_table(z,delim_whitespace=True)
Объяснение
Сначала вы aggregate
используете list
df.groupby(["Col1", "Col2"])[["Key", "Value"]].agg(list)
Key Value
Col1 Col2
101 a [f1, f2] [abc, def]
102 a [f2, f3] [xyz, fgh]
103 b [f1] [rst]
Затем transform
это вывод в словари и вообще переименование оси
.transform(lambda x: dict(zip(*x)),1).reset_index(name='kvpairs')
Col1 Col2 kvpairs
0 101 a {'f1': 'abc', 'f2': 'def'}
1 102 a {'f2': 'xyz', 'f3': 'fgh'}
2 103 b {'f1': 'rst'}
Наконец, используйте to_dict('records')
, чтобы получить список словарей
.to_dict('records')
[{'Col1': 101, 'Col2': 'a', 'kvpairs': {'f1': 'abc', 'f2': 'def'}},
{'Col1': 102, 'Col2': 'a', 'kvpairs': {'f2': 'xyz', 'f3': 'fgh'}},
{'Col1': 103, 'Col2': 'b', 'kvpairs': {'f1': 'rst'}}]