Python 在列中的最大日期结束熊猫石斑鱼 最小可重复示例 将numpy导入为np 作为pd进口熊猫 np.random.seed(0) 日期=pd.日期范围(开始日期为2021年1月1日,结束日期为2021年3月15日) df=pd.DataFrame({'date':np.random.choice(日期,1000), 'label':np.random.choice(['a','b','c'],1000)}) 结果 日期标签 0 2021-02-14 a 2021-02-17 c 2021-03-06A 3 2021-03-09 c 4 2021-03-09 b ... ... ... 995 2021-03-06 c 996 2021-01-14 b 997 2021-01-02 a 998 2021-01-03 c 999 2021-03-08 b

Python 在列中的最大日期结束熊猫石斑鱼 最小可重复示例 将numpy导入为np 作为pd进口熊猫 np.random.seed(0) 日期=pd.日期范围(开始日期为2021年1月1日,结束日期为2021年3月15日) df=pd.DataFrame({'date':np.random.choice(日期,1000), 'label':np.random.choice(['a','b','c'],1000)}) 结果 日期标签 0 2021-02-14 a 2021-02-17 c 2021-03-06A 3 2021-03-09 c 4 2021-03-09 b ... ... ... 995 2021-03-06 c 996 2021-01-14 b 997 2021-01-02 a 998 2021-01-03 c 999 2021-03-08 b,python,pandas,date,pandas-groupby,Python,Pandas,Date,Pandas Groupby,我试图从最后观察到的日期开始,每4周对日期列进行一次分组(在本例中,df['date'].max()给出'3/15/2021',因此我希望按日期和标签分组时的最后日期为'3/15/2021',并相应调整其他日期(3/15前28天、3/15前56天等) 但是,我无法使用pd.Grouper,pd.Grouper使用一个origin参数来调整分组,但是没有基于结束日期的选项 是否有一种类似于以下内容的方法来使用pd.Grouper: df.groupby([pd.Grouper(key='date'

我试图从最后观察到的日期开始,每4周对日期列进行一次分组(在本例中,
df['date'].max()
给出
'3/15/2021'
,因此我希望按日期和标签分组时的最后日期为
'3/15/2021'
,并相应调整其他日期(3/15前28天、3/15前56天等)

但是,我无法使用
pd.Grouper
pd.Grouper
使用一个
origin
参数来调整分组,但是没有基于结束日期的选项

是否有一种类似于以下内容的方法来使用
pd.Grouper

df.groupby([pd.Grouper(key='date',freq='28d',label='right'),'label'])['label'].count()

但相反,它将最后一组按日期结束设置为3/15(并且最后一组包含自3/15以来28天的所有数据)?

显然
pd。Grouper
不支持负频繁。我将决定按
Timedelta
进行分组:

out = (df.groupby((max_date-df['date'])//pd.Timedelta('28d'))
   ['label'].value_counts()
)

# relabel the index
out.index = pd.MultiIndex.from_tuples([
    (max_date - pd.to_timedelta(x*28, unit='D'),y) for x,y in out.index
], names=['date','label'])
输出:

date        label
2021-03-15  a        126
            b        124
            c        112
2021-02-15  b        138
            c        126
            a        120
2021-01-18  c         91
            b         87
            a         76
Name: label, dtype: int64

显然,
pd.Grouper
不支持负数频繁。我决定按
Timedelta
进行分组:

out = (df.groupby((max_date-df['date'])//pd.Timedelta('28d'))
   ['label'].value_counts()
)

# relabel the index
out.index = pd.MultiIndex.from_tuples([
    (max_date - pd.to_timedelta(x*28, unit='D'),y) for x,y in out.index
], names=['date','label'])
输出:

date        label
2021-03-15  a        126
            b        124
            c        112
2021-02-15  b        138
            c        126
            a        120
2021-01-18  c         91
            b         87
            a         76
Name: label, dtype: int64

我们可以尝试使用div创建日期计数

df_sub = df.assign(v = ((df.date-df.date.max()).dt.days.sub(1)//28))
s = df_sub.groupby(['v','label']).agg({'label':'count'})
s = s.join(df_sub.groupby('v').date.max())
Out[41]: 
          label       date
v  label                  
-3 a         76 2021-01-18
   b         87 2021-01-18
   c         91 2021-01-18
-2 a        120 2021-02-15
   b        138 2021-02-15
   c        126 2021-02-15
-1 a        126 2021-03-15
   b        124 2021-03-15
   c        112 2021-03-15

我们可以尝试使用div创建日期计数

df_sub = df.assign(v = ((df.date-df.date.max()).dt.days.sub(1)//28))
s = df_sub.groupby(['v','label']).agg({'label':'count'})
s = s.join(df_sub.groupby('v').date.max())
Out[41]: 
          label       date
v  label                  
-3 a         76 2021-01-18
   b         87 2021-01-18
   c         91 2021-01-18
-2 a        120 2021-02-15
   b        138 2021-02-15
   c        126 2021-02-15
-1 a        126 2021-03-15
   b        124 2021-03-15
   c        112 2021-03-15

我也考虑过这一点,但是如果数据中没有出现
2021-02-15
,则
date.max()
上的最后一次连接可能不起作用。@QuangHoang是的,这是正确的~我也考虑过这一点,但是如果数据中没有出现
2021-02-15
,则
date.max()
上一次连接可能不起作用。@QuangHoang是的,这是正确的~