September 17, 2022

3 неожиданности при группировке Pandas датафрейма

Рассмотрим кейсы на примере следующего датафрейма:

import pandas as pd
import numpy as np

df = pd.DataFrame({'id':[1, np.nan, 2, 2, np.nan, np.nan], 
                   'value':[np.nan,-2,3,2,5, np.nan]})
df

Пропажа Nan-ов

Сгруппируем данные по полю id и распределим сумму в value по всем членам поровну с записью в value_new:

df.groupby('id').apply(lambda df_part: 
                       df_part.assign(value_new=df_part['value'].sum()/df_part.shape[0]))

Члены с id равным Nan удалены из результата, чтобы их включить, достаточно установить параметр dropna в False:

df.groupby('id', dropna=False).apply(lambda df_part: 
                       df_part.assign(value_new=df_part['value'].sum()/df_part.shape[0]))

Сумма Nan-ов дает числовой результат

Результаты выше свидетельствуют, о том, что запись с id=1 имеет value = Nan, однако сумма по полю дает 0 и в итоге value_new=0. Еще более явно:

df.iloc[:1]['value'].sum()

Операция для группы Nan-ов дает результат

Из результатов группировки выше видно, что для записей с id=Nan в value_new записывается числовой результат.

Эти особенности бросаются в глаза при работе с маленьким датафреймом, но когда датасет большой, лучше быть готовым к таким сюрпризам.