在 pandas 数据帧上同时操作 groupby 和 resample?

Posted

技术标签:

【中文标题】在 pandas 数据帧上同时操作 groupby 和 resample?【英文标题】:Simultaneous operation of groupby and resample on pandas dataframe? 【发布时间】:2017-08-09 18:56:33 【问题描述】:

我的 pandas 数据框由一个分类列 JOB_TITLE、一个数字列 BASE_SALARY 和一个日期时间索引 JOIN_DATE 组成。我想对分类和下采样日期时间组进行聚合,如下所示:

# Resampled at frequency of start data of every 5 years
mean_agg = (df
          .groupby('JOB_TITLE')
          .resample('5AS')['BASE_SALARY']
          .mean())

不幸的是,由于 groupby 操作发生在重采样之前,因此重采样操作是针对每个 JOB_TITLE 组独立执行的。这导致以下系列:

| JOB_TITLE         | JOIN_DATE  |       |
|-------------------|------------|-------|
| Data Scientist    | 2004-01-01 | 60000 |
|                   | 2009-01-01 | 75000 |
|                   | 2014-01-01 | 90000 |
|                   |            |       |
| Software Engineer | 2001-01-01 | 70000 |
|                   | 2006-01-01 | 85000 |
|                   | 2011-01-01 | 90000 |
|                   | 2016-01-01 | 85000 |

如您所见,数据科学家组和软件工程师的 JOIN_DATE 级别的索引未对齐。当您为级别 JOB_TITLE 应用 unstack 时,这会产生问题,如下所示:

mean_agg.unstack('JOB_TITLE')

这会产生以下数据框:

| JOB_TITLE  | Data Scientist | Software Engineer |
|------------|----------------|-------------------|
| JOIN_DATE  |                |                   |
| 2001-01-01 | NaN            | 70000             |
| 2004-01-01 | 60000          | NaN               |
| 2006-01-01 | NaN            | 85000             |
| 2009-01-01 | 75000          | NaN               |
| 2011-01-01 | NaN            | 70000             |
| 2014-01-01 | 90000          | NaN               |
| 2016-01-01 | NaN            | 85000             |

如何避免 groupby 和 resample 的这种顺序操作,而是执行同时操作?谢谢!

【问题讨论】:

【参考方案1】:

更新 Pandas 0.21 答案:pd.TimeGrouper is getting deprecated,改用 pd.Grouper。

mean_agg = (df.groupby(['JOB_TITLE',pd.Grouper(freq='5AS')])['BASE_SALARY']
              .mean())

mean_agg.unstack('JOB_TITLE')

我们不使用重采样,而是尝试使用 pd.TimeGrouper

mean_agg = (df
      .groupby(['JOB_TITLE',pd.TimeGrouper(freq='5AS')])['BASE_SALARY']
      .mean())

mean_agg.unstack('JOB_TITLE')

TimeGrouper 对齐分组时间范围的 bin。

【讨论】:

太棒了! pd.TimeGrouper() 非常适合我的问题。【参考方案2】:

你可以使用 .reset_index()

day = pd.Grouper(freq='D')
df.set_index('JOIN_DATE').groupby(['JOB_TITLE', day]).BASE_SALARY.mean()

...或使用 pd.Grouper 中的 key 参数

day = pd.Grouper(key='JOIN_DATE', freq='D')
df.groupby(['JOB_TITLE', day]).BASE_SALARY.mean()

【讨论】:

以上是关于在 pandas 数据帧上同时操作 groupby 和 resample?的主要内容,如果未能解决你的问题,请参考以下文章

使用 pandas 在数据帧上执行 groupby,按计数排序并获取 python 中的前 2 个计数

Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)

Pandas groupby 类别,评级,从每个类别中获得最高价值?

Python/Pandas - 结合 groupby 平均值和最小值

spark - 在大型数据帧上执行 groupby 和聚合时,java 堆内存不足

具有两个分类变量的数据帧上的 Groupby 和 count() [重复]