Как объединить словари информационного кадра pandas при группировании по строкам

1

У меня есть 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 также было бы здорово, если бы решение было не слишком медленным, поскольку я должен сделать это для большого набора данных:/

  • 0
    Как вы хотите иметь дело с перекрывающимися ключами?
  • 0
    Вначале может быть проще сгладить ваши кадры данных (если имеется фиксированное количество возможных ключей). Просто заполните несуществующие значения с помощью NaN. Затем вы можете использовать все обычные методы объединения, предоставляя вам полный контроль (какой фрейм данных предпочитать, если оба имеют значения и т. Д.).
Показать ещё 2 комментария
Теги:
pandas
dataframe
pandas-groupby
dictionary

1 ответ

0
Лучший ответ

Вы почти там. Вам просто нужно использовать пользовательскую функцию, которая объединяет словари в значениях, отличных от нулевой:

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}
  • 1
    Большое спасибо! Работает отлично :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню