我有每年一次体育比赛的时间序列数据,以及每场比赛的举行日期。我想按游戏的季节(年)对游戏进行分组。每个季节都从8月开始,到7月结束。
我将如何按季节对游戏进行分组,例如- 季节(2016-2017),季节(2017-2018)等。
This Answer可能涉及df.resample(),但我不确定该怎么做。
这是日期列的样子:
DATE
26/09/09
04/10/09
17/10/09
25/10/09
31/10/09
...
29/09/18
07/10/18
28/10/18
03/11/18
我想按季节分组,以便可以对汇总数据执行可视化操作。
更新:目前,我的解决方案是将数据框分为32组,因为我知道每个赛季都有32场比赛。这是我使用的代码:
split_df = np.array_split(df, np.arange(0, len(df),32))
但是我宁愿选择更优雅,更包含时间序列数据的东西,所以我将继续公开这个问题。
答案 0 :(得分:2)
成功的关键是针对您的情况pd.Grouper(key='DATA', freq='AS-AUG')
进行适当的分组。
请注意,freq='AS-AUG'
指出您的网上论坛应从
每年八月。
查看以下脚本:
import pandas as pd
# Source columns
dates = [ '01/04/09', '31/07/09', '01/08/09', '26/09/09', '04/10/09', '17/12/09',
'25/01/10', '20/04/10', '31/07/10', '01/08/10', '28/10/10', '03/11/10',
'25/12/10', '20/04/11', '31/07/11' ]
scores_x = np.random.randint(0, 20, len(dates))
scores_y = np.random.randint(0, 20, len(dates))
# Source DataFrame
df = pd.DataFrame({'DATA': dates, 'SCORE_X': scores_x, 'SCORE_Y': scores_y})
# Convert string date to datetime
df.DATA = pd.to_datetime(df.DATA, format='%d/%m/%y')
# Groupping
gr = df.groupby(pd.Grouper(key='DATA', freq='AS-AUG'))
如果打印结果:
for name, group in gr:
print()
print(name)
print(group)
您将得到:
2008-08-01 00:00:00
DATA SCORE_X SCORE_Y
0 2009-04-01 16 11
1 2009-07-31 10 7
2009-08-01 00:00:00
DATA SCORE_X SCORE_Y
2 2009-08-01 19 6
3 2009-09-26 14 5
4 2009-10-04 8 11
5 2009-12-17 12 19
6 2010-01-25 0 0
7 2010-04-20 17 6
8 2010-07-31 18 2
2010-08-01 00:00:00
DATA SCORE_X SCORE_Y
9 2010-08-01 15 18
10 2010-10-28 2 4
11 2010-11-03 8 16
12 2010-12-25 13 1
13 2011-04-20 19 7
14 2011-07-31 8 3
如您所见,每个组从8月1日开始,到8月1日结束 7月31日。
您可以随心所欲地与小组合作。
答案 1 :(得分:1)
使用-
df.groupby(df['DATE'].dt.year).count()
输出
DATE
DATE
2009 5
2018 4
自定义季节分组
min_year = df['DATE'].dt.year.min()
max_year = df['DATE'].dt.year.max()
rng = pd.date_range(start='{}-07'.format(min_year), end='{}-08'.format(max_year), freq='12M').to_series()
df.groupby(pd.cut(df['DATE'], rng)).count()
输出
DATE
DATE
(2009-07-31, 2010-07-31] 3
(2010-07-31, 2011-07-31] 0
(2011-07-31, 2012-07-31] 0
(2012-07-31, 2013-07-31] 0
(2013-07-31, 2014-07-31] 0
(2014-07-31, 2015-07-31] 0
(2015-07-31, 2016-07-31] 0
(2016-07-31, 2017-07-31] 0
(2017-07-31, 2018-07-31] 1
答案 2 :(得分:1)
Resampling使用'A-JUL'
作为anchored offset alias应该可以解决问题:
>>> df
SAMPLE
DATE
2009-01-30 1
2009-07-10 4
2009-11-20 3
2010-01-01 5
2010-05-13 1
2010-08-01 1
>>> df.resample('A-JUL').sum()
SAMPLE
DATE
2009-07-31 5
2010-07-31 9
2011-07-31 1
A
表示每年一次,-JUL
表示每年7月结束。
答案 3 :(得分:0)
您可以建立一个季节专栏并以此分组。在下面的代码中,我使用pandas.DateOffset()
将所有日期都移回了7个月,因此,八月份发生的游戏看起来就像在一月份发生的那样,将季节年份与日历年份保持一致。在那之后,构建季节字符串非常简单。
import pandas as pd
from datetime import date
dates = pd.date_range(date(2009, 8, 1), date(2018, 7, 30), freq='17d')
df = pd.DataFrame(dates, columns=['date'])
# copy the date column to a separate dataframe to do the work
df_tmp = df[['date']]
df_tmp['season_start_year'] = (df_tmp['date'] - pd.DateOffset(months=7)).dt.year
df_tmp['season_end_year'] = df_tmp['season_start_year'] + 1
df_tmp['season'] = df_tmp['season_start_year'].map(str) + '-' + df_tmp['season_end_year'].map(str)
# copy season column to the main dataframe
df['season'] = df_tmp['season']
df.groupby('season').count()