агрегат pandas включает все группы

#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 добавить параметр в переиндексацию, но обычно необходимо создать новый мультииндекс.