#python #pandas
Вопрос:
В моем фрейме данных у меня есть несколько имен (строка), дат (datetime64) и количество наблюдений (число).
In [8]: df
Out[8]:
name date num
0 a 1 3
1 a 2 4
2 a 3 9
3 b 1 6
4 b 2 8
5 b 3 3
Что я хочу, так это рассчитать для каждого имени среднее актуальное значение. Поэтому я ожидаю, что для каждого имени будет следующий дополнительный столбец:
name date num avg
0 a 1 3 3
1 a 2 4 3.5
2 a 3 9 5.33
3 b 1 6 6
4 b 2 8 7
5 b 3 3 5.67
3 = 3/1; 3.5 = (3 4)/2; 5.33 = (3 4 9)/3 и так далее для любого другого имени.
Я пытался объединить функции панд groupby avg и cumsum, но не могу получить то, что я хочу.
Есть некоторые требования: мне нужно использовать функции pandas (без циклов) и в лучшем случае избегать использования лямбд, так как мой df большой.
Комментарии:
1. Ваши входные и ожидаемые выходные фреймы данных не совпадают. число индекса 5 изменилось с 3 до 9.
Ответ №1:
Использовать groupby
с expanding
и mean
:
df['avg'] = df.groupby('name')['num'].expanding().mean().reset_index(level=0, drop=True)
Выход:
name date num avg
0 a 1 3 3.000000
1 a 2 4 3.500000
2 a 3 9 5.333333
3 b 1 6 6.000000
4 b 2 8 7.000000
5 b 3 3 5.666667
Комментарии:
1. В столбце дата у меня есть несколько дат в будущем, и именно поэтому соответствующие значения num-это NaN. Если мы возьмем имя «а», например, я получу для дат 4, 5, 6 трижды 5.333333, 5.333333, 5.333333. Но вместо этого я хочу Нан. Как я могу это сделать?
2. @Android44 Вы добавляете такую маску
df.groupby('name')['num'].expanding().mean(skipna=True).reset_index(level=0, drop=True).mask(df['num'].isna())
Ответ №2:
Вы можете разделить совокупную сумму на совокупное количество (добавлено 1) для каждой группы:
g = df.groupby("name").num
df["avg"] = g.cumsum() / g.cumcount().add(1)
add(1)
где мы будем считать, так как это так, но нам нужно 0, 1, 2..
1, 2, 3..
,
получить
>>> df
name date num avg
0 a 1 3 3.000000
1 a 2 4 3.500000
2 a 3 9 5.333333
3 b 1 6 6.000000
4 b 2 8 7.000000
5 b 3 3 5.666667
Комментарии:
1. Что «num» предполагает делать? Я получаю сообщение об ошибке
2. @Android44, который выбирает
num
столбец после groupby (альтернативный синтаксис["num"]
). У тебя есть колонка с названиемnum
, верно? Не могли бы вы поделиться ошибкой, пожалуйста?3. Вы правы, в исходном наборе данных у меня есть другое имя столбца.