如何在非唯一列中按date分组pandasDataFrame条目

pandasDataFrame包含名为"date"列,其中包含非唯一的datetime值。 我可以在这个框架中使用以下几行:

 data.groupby(data['date']) 

但是,这会按datetime值拆分数据。 我想将这些数据按“date”列中存储的年份进行分组。 此页面显示如何将时间戳用作索引的情况下按年份分组,在我的情况下不是这样。

我如何实现这个分组?

ecatmur的解决scheme将正常工作。 但是,对于大型数据集,这将会有更好的性能:

 data.groupby(data['date'].map(lambda x: x.year)) 

我正在使用pandas0.16.2。 这在我的大数据集上有更好的性能:

 data.groupby(data.date.dt.year) 

使用dt选项和weekofyearweekofyear玩, weekofyear等变得更容易。

这应该工作:

 data.groupby(lambda x: data['date'][x].year) 

这可能更容易解释一个示例数据集。

创build示例数据

假设我们有一列时间戳, date和另一列,我们希望对其进行聚合。

 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属性的dt访问器
  • date放在索引中,使用匿名函数访问年份
  • 使用resample方法
  • 转换为pandas期间

.dtyear属性的访问器

当你有一个pandas时间戳列(而不是索引)时,你可以用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 

把date放在索引中,并使用匿名函数访问年份

如果将date列设置为索引,则它将成为具有与dt访问器给出正常列相同的属性和方法的DateTimeIndex

 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方法

如果date列不在索引中,则必须使用on参数指定列。 您还需要将偏移别名指定为string。

 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期间

您还可以将date列转换为pandas期间对象。 我们必须将偏移别名作为string传递来确定句点的长度。

 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 

这也将工作

data.groupby(data['date'].dt.year)