#pandas #pandas-groupby
#pandas #pandas-groupby
Вопрос:
У меня следующая проблема с агрегацией groupby, т.Е. Следует включить добавление групп, которые не представлены в dataframe, но основаны на желаемом результате. Пример:
import pandas as pd
from pandas.compat import StringIO
csvdata = StringIO("""day,sale
1,1
2,4
2,10
4,7
5,2.3
7,4.4
2,3.4""")
#day 3,6 are intentionally not included here but I'd like to have it in output
df = pd.read_csv(csvdata, sep=",")
df1=df.groupby(['day'])['sale'].agg('sum').reset_index().rename(columns={'sale':'dailysale'})
df1
Как я могу получить следующее? Спасибо!
1 1.0
2 17.4
3 0.0
4 7.0
5 2.3
6 0.0
7 4.4
Ответ №1:
Вы можете добавить Series.reindex
с указанным range
после агрегирования sum
:
df1 = (df.groupby(['day'])['sale']
.sum()
.reindex(range(1, 8), fill_value=0)
.reset_index(name='dailysale'))
print (df1)
day dailysale
0 1 1.0
1 2 17.4
2 3 0.0
3 4 7.0
4 5 2.3
5 6 0.0
6 7 4.4
Другая идея заключается в использовании ordered categorical
, поэтому агрегат sum
добавляет недостающие строки:
df['day'] = pd.Categorical(df['day'], categories=range(1, 8), ordered=True)
df1 = df.groupby(['day'])['sale'].sum().reset_index(name='dailysale')
print (df1)
day dailysale
0 1 1.0
1 2 17.4
2 3 0.0
3 4 7.0
4 5 2.3
5 6 0.0
6 7 4.4
Комментарии:
1. Отлично, спасибо! Мне понравился ваш 2-й вариант (перед редактированием!! ) потому что в моем случае может быть, что именно day1 отсутствует, поэтому включение этого приведет к отсутствию этого дня. если я укажу вручную, это будет безопаснее.
2. @physiker — Хорошо, добавь в ответ.
3. просто небольшой вопрос: как я могу конкретно указать переиндексацию для столбца дня? потому что в моем случае у меня есть несколько уровней groupby, и, по вашему совету, pandas, похоже, путают с переиндексацией индекса….
4. @physiker — попробуйте
axis=0, level=1
добавить параметр в переиндексацию, но обычно необходимо создать новый мультииндекс.