У меня есть dataframe формы:
id date area1 area2
01 20181010 {'a': 10, 'b': 15} {'a': 20, 'c': 13}
01 20181010 {'c': 17} {'b': 12}
02 20180506 {'a': 2, 'b': 3} {'c': 4}
02 20180506 Nan {'a': 18}
Я хотел бы сгруппировать все строки с соответствующими "id" и "date", объединяя словари "area1" и "area2". Значение, которое я хотел бы получить:
id date area1 area2
01 20181010 {'a': 10, 'b': 15, 'c': 17} {'a': 20, 'c': 13, 'b': 12}
02 20180506 {'a': 2, 'b': 3} {'c': 4, 'a': 18}
Сначала я пытался что-то вроде:
merged_df = df.groupby(["id", "date"],as_index=False).agg({'area1':'first', 'area2': 'first'})
Очевидно, что это получает только первый запрос area1 и area2. Но если я правильно понимаю, можно передать функцию в agg, так можно ли было бы объединить словари? Я просто не могу сказать, чтобы он взял следующий дикт и объединил его (учитывая, что он может не существовать и быть Нан).
Большое спасибо!
Ahh также было бы здорово, если бы решение было не слишком медленным, поскольку я должен сделать это для большого набора данных:/
Вы почти там. Вам просто нужно использовать пользовательскую функцию, которая объединяет словари в значениях, отличных от нулевой:
def merge_dicts(x):
return {k: v for d in x.dropna() for k, v in d.items()}
res = df.groupby(['id', 'date'], as_index=False).agg(merge_dicts)
print(res)
id date area1 area2
0 01 20181010 {'a': 10, 'b': 15, 'c': 17} {'a': 20, 'c': 13, 'b': 12}
1 02 20180506 {'a': 2, 'b': 3} {'c': 4, 'a': 18}