使用带有多个键的 Grouper 时填写缺失的日期

Posted

技术标签:

【中文标题】使用带有多个键的 Grouper 时填写缺失的日期【英文标题】:Fill missing dates while using Grouper with multiple keys 【发布时间】:2020-02-06 15:45:04 【问题描述】:

我有一个时间序列数据集,其中包含 3 年内不同材料的消耗量。我正在尝试在材料级别汇总此数据集,其中包含每月的消耗量。虽然我可以使用带有多个键的 Grouper 来执行此操作,但最终输出中缺少消耗为 0 的月份。有人可以帮我如何包含这些月份吗?

我尝试使用带有多个键的 pandas Grouper。

grouper = pd.Grouper(key='Date',freq='MS')
consumption_grouped = consumption.groupby([pd.Grouper(key='Material'),grouper])['QtyConsumed'].sum().reset_index()

预期

Date          QtyConsumed
2017-08-01   -2.0
2017-09-01   -8.0
2017-10-01   -6.0
2017-11-01   -2.0
2017-12-01    0.0
2018-01-01   -3.0

实际

Date          QtyConsumed
2017-08-01   -2.0
2017-09-01   -8.0
2017-10-01   -6.0
2017-11-01   -2.0
2018-01-01   -3.0

如您在上面看到的,在实际结果中,缺少 2017-12-01 的条目。

【问题讨论】:

【参考方案1】:

你必须重新采样,而不是分组

df['Date']=pd.to_datetime(df['Date'])
df.set_index('Date').resample('MS').last().fillna(0).reset_index()

输入

          Date  QtyConsumed
0   2017-08-01  -2.0
1   2017-09-01  -8.0
2   2017-10-01  -6.0
3   2017-11-01  -2.0
4   2018-01-01  -3.0

输出

         Date   QtyConsumed
0   2017-08-01  -2.0
1   2017-09-01  -8.0
2   2017-10-01  -6.0
3   2017-11-01  -2.0
4   2017-12-01  0.0
5   2018-01-01  -3.0

【讨论】:

【参考方案2】:

解决方案如果MultiIndex 由输入DataFrame 中的前2 列首先由DataFrame.reset_indexMaterial 级别创建DatetimeIndex,然后将groupbyDataFrameGroupBy.resamplesum 一起使用:

print (df)
                     QtyConsumed
Material Date                   
mat1     2017-08-01         -2.0
         2017-09-01         -8.0
         2017-10-01         -6.0
         2017-11-01         -2.0
         2018-01-01         -3.0
mat2     2017-08-01         -2.0
         2017-09-01         -8.0
         2017-10-01         -6.0
         2017-11-01         -2.0
         2018-01-01         -3.0
mat3     2017-08-01         -2.0
         2017-09-01         -8.0
         2017-10-01         -6.0
         2017-11-01         -2.0
         2018-01-01         -3.0

df = (df.reset_index(level=['Material'])
        .groupby('Material')
        .resample('MS')['QtyConsumed']
        .sum()
        .reset_index())
print (df)
   Material       Date  QtyConsumed
0      mat1 2017-08-01         -2.0
1      mat1 2017-09-01         -8.0
2      mat1 2017-10-01         -6.0
3      mat1 2017-11-01         -2.0
4      mat1 2017-12-01          0.0
5      mat1 2018-01-01         -3.0
6      mat2 2017-08-01         -2.0
7      mat2 2017-09-01         -8.0
8      mat2 2017-10-01         -6.0
9      mat2 2017-11-01         -2.0
10     mat2 2017-12-01          0.0
11     mat2 2018-01-01         -3.0
12     mat3 2017-08-01         -2.0
13     mat3 2017-09-01         -8.0
14     mat3 2017-10-01         -6.0
15     mat3 2017-11-01         -2.0
16     mat3 2017-12-01          0.0
17     mat3 2018-01-01         -3.0

如果只有DatetimeIndex:

print (df)
           Material  QtyConsumed
Date                            
2017-08-01     mat1         -2.0
2017-09-01     mat1         -8.0
2017-10-01     mat1         -6.0
2017-11-01     mat1         -2.0
2018-01-01     mat1         -3.0
2017-08-01     mat2         -2.0
2017-09-01     mat2         -8.0
2017-10-01     mat2         -6.0
2017-11-01     mat2         -2.0
2018-01-01     mat2         -3.0
2017-08-01     mat3         -2.0
2017-09-01     mat3         -8.0
2017-10-01     mat3         -6.0
2017-11-01     mat3         -2.0
2018-01-01     mat3         -3.0

df = (df.groupby('Material')
        .resample('MS')['QtyConsumed']
        .sum()
        .reset_index())
print (df)
   Material       Date  QtyConsumed
0      mat1 2017-08-01         -2.0
1      mat1 2017-09-01         -8.0
2      mat1 2017-10-01         -6.0
3      mat1 2017-11-01         -2.0
4      mat1 2017-12-01          0.0
5      mat1 2018-01-01         -3.0
6      mat2 2017-08-01         -2.0
7      mat2 2017-09-01         -8.0
8      mat2 2017-10-01         -6.0
9      mat2 2017-11-01         -2.0
10     mat2 2017-12-01          0.0
11     mat2 2018-01-01         -3.0
12     mat3 2017-08-01         -2.0
13     mat3 2017-09-01         -8.0
14     mat3 2017-10-01         -6.0
15     mat3 2017-11-01         -2.0
16     mat3 2017-12-01          0.0
17     mat3 2018-01-01         -3.0

【讨论】:

以上是关于使用带有多个键的 Grouper 时填写缺失的日期的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:填写每个实体具有不同日期范围的缺失日期

pd.Grouper() 应用于日期时间时,更改原始日期列

在 Postgres 中聚合多个字段时填写缺失的行

填写缺失的日期 Redshift

填写缺失的日期值并根据前一行填充第二列

转发新行填写缺失日期的帐户