【问题标题】:Create new rolling mean column with GroupBy on multiple columns在多列上使用 GroupBy 创建新的滚动平均列
【发布时间】:2020-05-07 09:40:40
【问题描述】:

我有一个包含 11 列的数据框,其中 date 是一个索引。我正在尝试使用列total 的滚动平均值创建一个新列。但是,我收到错误:TypeError:插入列的索引与框架索引不兼容

import pandas as pd

df = pd.DataFrame({
    'date':['2016-04-01','2016-05-01','2016-07-01','2016-08-01','2016-09-01',  '2019-04-01','2019-05-01','2019-06-01','2019-08-01','2019-09-01'],
    'Country':['USA', 'USA', 'USA', 'USA', 'USA','USA', 'USA', 'USA', 'USA', 'USA'],
    'Region':['Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern'],
    'State':['New York','New York','New York','New York','New York','New York','New York','New York','New York','New York'],
    'Supplier':['ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC'],
    'Location':['Bin-1', 'Bin-1', 'Bin-1', 'Bin-1', 'Bin-1','Bin-1', 'Bin-1', 'Bin-1', 'Bin-1', 'Bin-1'],
    'Year':[2016,2016,2016,2016,2016,2019,2019,2019,2019,2019],
    'Month':[4,5,7,8,9,4,5,6,8,9],
    'periodcode':[4,5,7,8,9,4,5,6,8,9],
    'Product':['bike','bike','bike','bike','bike','bike','bike','bike','bike','bike'],
    'total':[0,2000,1000,4000,0,2000,2000,1000,4000,600]})
df.set_index('date', inplace=True)

df['mean'] = df.groupby(['Country','Region','State','Supplier','Location','Product'], as_index=False)['total'].rolling(3).mean().reset_index(level=0,drop=True)
df.head(10)

但是,当我将year 列包含到groupby 中时,即

df['mean'] = df.groupby(['Country','Region','State','Supplier','Location','Product','Year'], as_index=False)['total'].rolling(3).mean().reset_index(level=0,drop=True) 

我计算出滚动平均值。这个问题是,我希望分组排除Year

有什么想法吗?

【问题讨论】:

  • 您能描述一下您要计算的内容吗?您希望在每一行中看到哪个“意思”?

标签: python pandas pandas-groupby


【解决方案1】:

由于根据我们在下面的 cmets 中的讨论,您希望计算每组跨年的滚动平均值,以下应该会给您想要的结果:

df['mean'] = df.groupby(['Country','Region','State','Supplier','Location','Product'])['total'].rolling(3).mean().reset_index().set_index("date")['total']

关键是保留date 索引(它允许您将计算的滚动平均值与原始数据框中的一行匹配)并提取从列total 的滚动平均值计算返回的Series 对象。

更详细的解释:

您的问题是没有Yeargroupby 会导致DataFramedf 不兼容,因此无法分配给df["mean"]

第一个变体给出了Series 女巫匹配索引:

df.groupby(['Country','Region','State','Supplier','Location','Product','Year'], as_index=False)['total'].rolling(3).mean().reset_index(level=0,drop=True)

date
2016-04-01            NaN
2016-05-01            NaN
2016-07-01    1000.000000
2016-08-01    2333.333333
2016-09-01    1666.666667
2019-04-01            NaN
2019-05-01            NaN
2019-06-01    1666.666667
2019-08-01    2333.333333
2019-09-01    1866.666667
Name: total, dtype: float64

但是,第二个变体(没有Year)会产生DataFrame,其中date 列中的每个条目都成为自己的列。因此,您不能将其分配给df["mean"]

此问题的解决方案实际上取决于您要解决的问题。但是,从概念上讲,如果您将 date 作为索引,则您分配给 df["mean"]Series 中的每个 date 只能有一个值。

【讨论】:

  • 整个数据集有超过 10 万条记录,涉及不同的地区、州、供应商、地点、产品和年份。我想根据这些字段运行滚动平均值。以为我可以使用索引(日期)字段将系列合并回数据框
  • 你当然可以做到!我目前不知道的是为什么要从groupby 中排除年份。直观地说,我假设您希望获得滚动平均值每年,但这里似乎并非如此?为了将平均值加回df,每个date 最多需要获得一个值。
  • 嗯,我排除它的简单原因是因为需要 11 月和 12 月的总数来计算 1 月的平均值。否则,我最终会得到一个 NAN。滚动平均值用于后续计算。我希望能够允许最终用户增加或减少滚动窗口。希望这可以澄清它
  • 我明白了。我为我的答案添加了一个可能的解决方案。它可能可以稍微调整一下,但是根据您提供的测试数据,它似乎返回了所需的结果。
猜你喜欢
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 2021-08-07
  • 1970-01-01
相关资源
最近更新 更多