Pandas DataFrame
包含名为"date"
的列,其中包含非唯一datetime
值。
我可以使用以下方法对此框架中的线进行分组:
data.groupby(data['date'])
但是,这会将数据按datetime
值拆分。我想按照“日期”列中存储的年份对这些数据进行分组。 This page显示了在时间戳用作索引的情况下如何按年分组,在我的情况下不是这样。
如何实现此分组?
答案 0 :(得分:69)
ecatmur的解决方案将正常运行。不过,这对大型数据集的性能会更好:
data.groupby(data['date'].map(lambda x: x.year))
答案 1 :(得分:62)
我正在使用熊猫0.16.2。这在我的大型数据集上具有更好的性能:
data.groupby(data.date.dt.year)
使用dt
选项并使用weekofyear
,dayofweek
等变得容易得多。
答案 2 :(得分:14)
使用样本数据集可能更容易解释。
创建示例数据
假设我们有一列时间戳date
和另一列我们想要对a
执行聚合。
df = pd.DataFrame({'date':pd.DatetimeIndex(['2012-1-1', '2012-6-1', '2015-1-1', '2015-2-1', '2015-3-1']),
'a':[9,5,1,2,3]}, columns=['date', 'a'])
df
date a
0 2012-01-01 9
1 2012-06-01 5
2 2015-01-01 1
3 2015-02-01 2
4 2015-03-01 3
有多种方法可以按年分组
year
属性date
放入索引并使用匿名函数访问年份resample
方法.dt
属性的year
访问者
如果您拥有pandas Timestamps的列(而不是索引),则可以使用dt
访问者访问更多其他属性和方法。例如:
df['date'].dt.year
0 2012
1 2012
2 2015
3 2015
4 2015
Name: date, dtype: int64
我们可以使用它来形成我们的组并计算特定列的一些聚合:
df.groupby(df['date'].dt.year)['a'].agg(['sum', 'mean', 'max'])
sum mean max
date
2012 14 7 9
2015 6 2 3
如果将日期列设置为索引,它将成为DateTimeIndex,其具有与dt
访问器相同的属性和方法,以提供常规列
df1 = df.set_index('date')
df1.index.year
Int64Index([2012, 2012, 2015, 2015, 2015], dtype='int64', name='date')
有趣的是,使用groupby方法时,可以传递一个函数。此函数将隐式传递DataFrame的索引。因此,我们可以从上面得到相同的结果:
df1.groupby(lambda x: x.year)['a'].agg(['sum', 'mean', 'max'])
sum mean max
2012 14 7 9
2015 6 2 3
resample
方法如果您的日期列不在索引中,则必须使用on
参数指定列。您还需要将offset alias指定为字符串。
df.resample('AS', on='date')['a'].agg(['sum', 'mean', 'max'])
sum mean max
date
2012-01-01 14.0 7.0 9.0
2013-01-01 NaN NaN NaN
2014-01-01 NaN NaN NaN
2015-01-01 6.0 2.0 3.0
您还可以将日期列转换为pandas Period对象。我们必须将偏移别名作为字符串传递,以确定Period的长度。
df['date'].dt.to_period('A')
0 2012
1 2012
2 2015
3 2015
4 2015
Name: date, dtype: object
然后我们可以将其作为一个组使用
df.groupby(df['date'].dt.to_period('Y'))['a'].agg(['sum', 'mean', 'max'])
sum mean max
2012 14 7 9
2015 6 2 3
答案 3 :(得分:13)
这应该有效:
data.groupby(lambda x: data['date'][x].year)
答案 4 :(得分:0)
这也可行
data.groupby(data['date'].dt.year)