【问题标题】:Pandas - rolling mean with groupby熊猫 - groupby 的滚动平均值
【发布时间】:2019-07-27 03:05:21
【问题描述】:

我是熊猫新手。 我有一个数据框,我正在查看 Horse 结果。 我试图在每匹马的最后 30 天的列中获得位置完成结果的滚动平均值。这是数据框中的两匹马的示例:

        Horse            Position  OR   RaceDate    Weight
125283  cookie ring             4  59.0 2016-04-25  52.272727
126134  a boy named sue         7  46.0 2016-05-31  54.090909
137654  a boy named sue         4  49.0 2017-01-25  57.727273
138434  a boy named sue         8  48.0 2017-02-04  55.909091
138865  a boy named sue         2  48.0 2017-02-10  51.363636
140720  a boy named sue         3  50.0 2017-03-10  54.545455
141387  a boy named sue         7  49.0 2017-03-22  59.545455
143850  cookie ring             11  54.0 2017-05-25 56.818182
144203  cookie ring             9  54.0 2017-06-03  50.000000

所以我需要对每匹马进行分组,然后应用 90 天的滚动平均值。我正在通过以下方式调用:

df['PositionAv90D'] = df.set_index('RaceDate').groupby('Horse').rolling("90d")['Position'].mean().reset_index()

但这会返回一个包含 3 列的数据框,并且仍然索引到 Horse。此处示例:

0          a b celebration 2011-08-24       3.000000
1          a b celebration 2011-09-15       4.500000
2          a b celebration 2012-05-29       4.000000
3        a beautiful dream 2016-10-21       2.333333
4        a big sky brewing 2008-04-11       2.000000
5        a big sky brewing 2008-07-08       7.500000
6        a big sky brewing 2008-08-11      10.000000
7        a big sky brewing 2008-09-20       9.000000
8        a big sky brewing 2008-12-30       4.333333
9        a big sky brewing 2009-01-21       3.666667
10       a big sky brewing 2009-02-20       3.777778

我需要一个与原始数据框索引相同的列。

你能帮忙吗?

【问题讨论】:

  • 您期待什么?此外,如果您的示例数据匹配,它会更有帮助。尝试获取数据框的一个小样本,然后对该小样本执行计算。

标签: python pandas


【解决方案1】:

使用set_index() 将删除原始索引,因此首先使用reset_index() 将创建一个名为“index”的新列,其中包含您的原始索引。然后在最后插入 reset_index() (它只是创建一个索引 0、1、2...等)使用 set_index('index') 回到原来的

因此,如果您执行以下操作,我认为它会起作用:

df['PositionAv90D'] = df.reset_index().set_index('RaceDate').groupby('Horse').rolling("90d")['Position'].mean().set_index('index')

一个简单的数据样本可以很好地对其进行测试,根据您提供的数据重新创建它有点困难

编辑 1:

由于您正在切换索引,因此更容易拆分一些,请参见下文,我创建了一些示例数据,我认为这些数据与您所获得的数据相似:

df = pd.DataFrame({'foo': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
                   'bar': [1, 1, 1, 2, 2, 2, 3, 3, 3],
                   'baz': [11, 12, 13, 14, 15, 16, 17, 18, 19]},
                  index = [14, 15, 16, 17, 18, 19, 20, 21, 22])

df.reset_index(inplace=True)    # This gives us index 0,1,2... and a new col 'index'
df.set_index('baz', inplace=True)    # Replace with date in yours
# This next bit does the groupby and rolling, which will give a df 
# with a multi index of foo and baz, then reset_index(0) to remove the foo index level
# so that it matches the original df index so that you can add it as a new column
df['roll'] = df.groupby('foo')['bar'].rolling(3).sum().reset_index(0,drop=True)
df.reset_index(inplace=True)    # brings baz back into the df as a column
df.set_index('index', inplace=True)   # sets the index back to the original

这将在原始 df 中为您提供一个带有滚动值的新列。在我的示例中,每个组中的前 2 个值将具有 NaN,因为窗口仅以 idx = 窗口大小开始。因此,在您的情况下,每组的前 89 天将是 NaN。您可能需要添加一个额外的步骤来从生成的 DataFrame 中仅选择过去 30 天

【讨论】:

  • 实际上这是行不通的,因为当您执行rolling("90d")['Position'] 时,您只选择了每个组中的位置列,因此您只能取回索引、组列和位置列,因此为什么你只看到 3 个返回(因为你已经完成了 reset_index() 有一个额外的新索引)
  • 已添加更新以将原始列保留在结果数据框中
猜你喜欢
  • 1970-01-01
  • 2023-02-17
  • 2018-04-26
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多