添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

每周一组python pandas数据框架(从周一开始)。

7 人关注

我有一个每天都有数值的数据框架(见下面的df)。 我想将 "预测 "字段按周分组,但以周一为一周的第一天。

目前我可以通过pd.TimeGrouper('W')来做(见下面的df_final),但它将一周的时间从周日开始分组(见下面的df_final)。

import pandas as pd
data = [("W1","G1",1234,pd.to_datetime("2015-07-1"),8),
        ("W1","G1",1234,pd.to_datetime("2015-07-30"),2),
        ("W1","G1",1234,pd.to_datetime("2015-07-15"),2),
        ("W1","G1",1234,pd.to_datetime("2015-07-2"),4),
        ("W1","G2",2345,pd.to_datetime("2015-07-5"),5),
        ("W1","G2",2345,pd.to_datetime("2015-07-7"),1),
        ("W1","G2",2345,pd.to_datetime("2015-07-9"),1),
        ("W1","G2",2345,pd.to_datetime("2015-07-11"),3)]
labels = ["Site","Type","Product","Date","Forecast"]
df = pd.DataFrame(data,columns=labels).set_index(["Site","Type","Product","Date"])
                              Forecast
Site Type Product Date                
W1   G1   1234    2015-07-01         8
                  2015-07-30         2
                  2015-07-15         2
                  2015-07-02         4
     G2   2345    2015-07-05         5
                  2015-07-07         1
                  2015-07-09         1
                  2015-07-11         3
df_final = (df
     .reset_index()
     .set_index("Date")
     .groupby(["Site","Product",pd.TimeGrouper('W')])["Forecast"].sum()
     .astype(int)
     .reset_index())
df_final["DayOfWeek"] = df_final["Date"].dt.dayofweek
df_final
  Site  Product       Date  Forecast  DayOfWeek
0   W1     1234 2015-07-05        12          6
1   W1     1234 2015-07-19         2          6
2   W1     1234 2015-08-02         2          6
3   W1     2345 2015-07-05         5          6
4   W1     2345 2015-07-12         5          6
    
1 个评论
我认为 W-MON 代替 W 应该有帮助。
python
pandas
datetime
pandas-groupby
Nicolas
Nicolas
发布于 2017-10-04
2 个回答
jezrael
jezrael
发布于 2021-03-24
已采纳
0 人赞同

Use W-MON instead W , check 锚定的偏移量 :

df_final = (df
     .reset_index()
     .set_index("Date")
     .groupby(["Site","Product",pd.Grouper(freq='W-MON')])["Forecast"].sum()
     .astype(int)
     .reset_index())
df_final["DayOfWeek"] = df_final["Date"].dt.dayofweek
print (df_final)
  Site  Product       Date  Forecast  DayOfWeek
0   W1     1234 2015-07-06        12          0
1   W1     1234 2015-07-20         2          0
2   W1     1234 2015-08-03         2          0
3   W1     2345 2015-07-06         5          0
4   W1     2345 2015-07-13         5          0
    
TimeGrouper is 现已弃用
tozCSS
tozCSS
发布于 2021-03-24
0 人赞同

对于这个问题,我有三个解决方案,如下所述。首先,我应该说明,以前接受的答案是不正确的。原因是这样的。

# let's create an example df of length 9, 2020-03-08 is a Sunday
s = pd.DataFrame({'dt':pd.date_range('2020-03-08', periods=9, freq='D'),
                  'counts':0})

这个分组器实际上是按照我们的要求进行分组的(周一到周日),但是在 "dt "上标注了一周的结束时间,而不是开始时间。所以,为了得到我们想要的东西,我们可以将索引移动6天,比如。

w = s.groupby(pd.Grouper(key='dt', freq='W')).count()
w.index -= pd.Timedelta(days=6)

或者,我们也可以这样做。

s.groupby(pd.Grouper(key='dt',freq='W-Mon',label='left',closed='left')).count()

第三种解决方案,可以说是最易读的一种,是先将dt转换为周期,然后分组,最后(如果需要)再转换回时间戳。

s.groupby(s.dt.dt.to_period('W'))['counts'].count().to_timestamp()
# a variant of this solution is: s.set_index('dt').to_period('W').groupby(pd.Grouper(freq='W')).count().to_timestamp()

所有这些解决方案都返回了OP所要求的东西。