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
我试图从最后观察到的日期开始,每4周对日期列进行一次分组(在本例中,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'
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是的,这是正确的~