python - 填充 pandas 中多索引数据框的所有月份

标签 python pandas datetime multi-index

我有一张表格,其中包含 2015 年至 2017 年期间数千种产品的每月销售额和预测。 我的数据给出了每个站点、类型、产品和日期(仅几个月)的需求和预测

问题是,如果一个月内没有销售且没有预测,我看不到具体的行。在下面的示例中,您会看到缺少“2015-08-31”行。 我希望看到这条线的需求为 0,预测为 0。 (请参阅下面的 df_expected 示例)。

基本上,对于 2015 年 6 月 30 日到 2017 年 9 月 30 日之间的所有产品/类型/网站组合,我想用 0 填充此表。

正如您在代码中看到的,我没有定义任何索引,但基本上 ["Site","Type","Product","Date"] 可以被视为多索引。

请注意,我有数百万行。

    import pandas as pd
data = [("W1","G1",1234,pd.to_datetime("2015-07-31"),8,4),
        ("W1","G1",1234,pd.to_datetime("2015-09-30"),2,4),
        ("W1","G1",1234,pd.to_datetime("2015-10-31"),2,4),
        ("W1","G1",1234,pd.to_datetime("2015-11-30"),4,4),
        ("W1","G2",2345,pd.to_datetime("2015-07-31"),5,0),
        ("W1","G2",2345,pd.to_datetime("2015-08-31"),1,3),
        ("W1","G2",2345,pd.to_datetime("2015-10-31"),1,3),
        ("W1","G2",2345,pd.to_datetime("2015-11-30"),3,3)]
labels = ["Site","Type","Product","Date","Demand","Forecast"]
df = pd.DataFrame(data,columns=labels)
df

   Site Type  Product       Date  Demand  Forecast
0   W1   G1     1234 2015-07-31       8         4
1   W1   G1     1234 2015-09-30       2         4
2   W1   G1     1234 2015-10-31       2         4
3   W1   G1     1234 2015-11-30       4         4
4   W1   G2     2345 2015-07-31       5         0
5   W1   G2     2345 2015-08-31       1         3
6   W1   G2     2345 2015-10-31       1         3
7   W1   G2     2345 2015-11-30       3         3

这就是我期待的结果

data_expected = [("W1","G1",1234,pd.to_datetime("2015-07-31"),8,4),
                 ("W1","G1",1234,pd.to_datetime("2015-08-31"),0,0),
                 ("W1","G1",1234,pd.to_datetime("2015-09-30"),2,4),        
                 ("W1","G1",1234,pd.to_datetime("2015-10-31"),2,4),
                 ("W1","G1",1234,pd.to_datetime("2015-11-30"),4,4)]
df_expected = pd.DataFrame(data_expected,columns=labels)
df_expected

  Site Type  Product        Date  Demand  Forecast
0   W1   G1     1234  2015-07-31       8         4
1   W1   G1     1234  2015-08-31       0         0
2   W1   G1     1234  2015-09-30       2         4
3   W1   G1     1234  2015-10-31       2         4
4   W1   G1     1234  2015-11-30       4         4

我最初考虑的是 stack/unstack 来确保我有所有的月份。但这对于具有数百万行的数据框来说并不是最佳选择。

df = (df
      .set_index("Date")
      .groupby(["Site","Product","Type",pd.TimeGrouper('M')])[["Forecast","Demand"]].sum()
      .unstack()
      .fillna(0)
      .astype(int))

你觉得怎么样?

最佳答案

您可以使用DataFrameGroupBy.resampleasfreq :

df = (df.set_index('Date')
       .groupby(["Site","Type","Product"])['Demand','Forecast']
       .resample('M')
       .asfreq()
       .fillna(0)
       .astype(int)
       .reset_index())
print (df)
  Site Type  Product       Date  Demand  Forecast
0   W1   G1     1234 2015-07-31       8         4
1   W1   G1     1234 2015-08-31       0         0
2   W1   G1     1234 2015-09-30       2         4
3   W1   G1     1234 2015-10-31       2         4
4   W1   G1     1234 2015-11-30       4         4

编辑:

我尝试使用 unstack 中的 fill_value 参数稍微改进原始解决方案:

(df.set_index("Date") 
   .groupby(["Site","Product","Type",pd.TimeGrouper('M')])['Dem‌​and','Forecast'].sum‌​() 
   .unstack(fill_value=0) 
   .stack())

关于python - 填充 pandas 中多索引数据框的所有月份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46427186/

相关文章:

python - opencv中的相机校准(Python立体相机)。错误:解包的值(value)太多

模块之间的python全局变量

python - 使用 pandas dataframe 在 python 中将 utf 转换为 ascii

python - 如何在具有不同 Y 轴的同一 seaborn 图中很好地制作条形图和线图?

python - 如何在 Python 中找到从周日开始的周数?

PHP fatal error : Call to a member function format() on boolean

javascript - 在带有 Jinja/Flask 的 Javascript 文件中使用 url_for()

python - 使用 Python 解析 pflog 文件

python - 没有创建它应该创建的 csv 文件

python-3.x - 日期时间字符串到纪元 : pandas dataframe