使用 Pandas 计算 rolling.mean 时忽略给定列的前面的值

Ignore preceding values for a given column when calculating rolling.mean using Pandas

这是我拥有的非常小的时间序列数据子集:

Date              Client        Value
01-Sep-2016T      ABC           160000
02-Sep-2016T      ABC           150000
03-Sep-2016T      ABC           190000
04-Sep-2016T      ABC           200000
05-Sep-2016T      ABC           140000
06-Sep-2016T      ABC           120000
07-Sep-2016T      ABC           185000
08-Sep-2016T      ABC           119000
01-Sep-2016T      DEF           200
02-Sep-2016T      DEF           100
03-Sep-2016T      DEF           150
04-Sep-2016T      DEF           10
05-Sep-2016T      DEF           5
06-Sep-2016T      DEF           160
07-Sep-2016T      DEF           150
08-Sep-2016T      DEF           3

我创建一个数据框,如下:

dataFrame = pd.read_csv('test_data_02.csv')

然后,我尝试在Value列中添加一条移动平均线,如下:

dataFrame['Value_MovingAverage'] = dataFrame['Value'].rolling(window=3, min_periods=1, center=False).mean()

然后,当我调用 dataFrame.head(20) 查看结果 ValueMovingAverage 列时,我看到:

    Date      Client    Value     Value_MovingAverage
0   01-Sep    ABC       160000    160000.000000
1   02-Sep    ABC       150000    155000.000000
2   03-Sep    ABC       190000    166666.666667
3   04-Sep    ABC       200000    180000.000000
4   05-Sep    ABC       140000    176666.666667
5   06-Sep    ABC       120000    153333.333333
6   07-Sep    ABC       185000    148333.333333
7   08-Sep    ABC       119000    141333.333333
8   01-Sep    DEF       200       **101400.000000**
9   02-Sep    DEF       100       39766.666667
10  03-Sep    DEF       150       150.000000
11  04-Sep    DEF       10        86.666667
12  05-Sep    DEF       5         55.000000
13  06-Sep    DEF       160       58.333333
14  07-Sep    DEF       150       105.000000
15  08-Sep    DEF       3         104.333333

正如我们所见,'DEF' 客户的 Value_MovingAverage 受到前两个 'ABC' 客户的非常高的值的影响。例如,索引 #8 显示 'DEF' 的 3 天移动平均值为 101400.000000,因为它使用以下值:

185,000 119,000 200

平均 --> 101400

我试图让索引 # 8 的 Value_MovingAverage 不显示任何内容(因为客户端 'ABC' 没有前面的值)和索引 # 14 显示 Value_MovingAverage 的 58.33333,因为它引用了以下内容:

160 10 5个 平均值 --> 58.33333

我的问题是:

1) 如何告诉 Pandas 在计算 'DEF' 客户的移动平均值时忽略 'ABC' 的值(对于所有其他 'Client' 整个数据框中的值)?请注意,我有数百个 'Client' 值,因此创建不同的帧(每个帧一个 'Client')然后应用滚动平均值并不是一个真正的选择。

2) 如何将移动平均值偏移一行,以便给定行数的平均值不考虑 本身

提前致谢!

我为您提供了一个解决方案,它不会直接回答您提出的具体问题,但可能会解决您实际遇到的问题 ;)

即:Pandas 的 groupby 特征。

显然你的数据集不是只是一个简单的时间序列。它是一堆时间序列,由 'ABC'、'DEF' 等的不同值连接而成。

在宏伟的计划中,您似乎知道如何使用 pandas 东西(例如 rolling),所以我留给您弄清楚如何使用 groupby ,但如果您无法让它工作,请随时 return 提出更多问题 :)

更新:

In [41]: df['new'] = (df.groupby('Client', as_index=False)
   ....:                .rolling(3, min_periods=1, center=False)
   ....:                .Value.mean()
   ....:                .reset_index(drop=True))

In [42]: df
Out[42]:
            Date Client   Value            new
0   01-Sep-2016T    ABC  160000  160000.000000
1   02-Sep-2016T    ABC  150000  155000.000000
2   03-Sep-2016T    ABC  190000  166666.666667
3   04-Sep-2016T    ABC  200000  180000.000000
4   05-Sep-2016T    ABC  140000  176666.666667
5   06-Sep-2016T    ABC  120000  153333.333333
6   07-Sep-2016T    ABC  185000  148333.333333
7   08-Sep-2016T    ABC  119000  141333.333333
8   01-Sep-2016T    DEF     200     200.000000
9   02-Sep-2016T    DEF     100     150.000000
10  03-Sep-2016T    DEF     150     150.000000
11  04-Sep-2016T    DEF      10      86.666667
12  05-Sep-2016T    DEF       5      55.000000
13  06-Sep-2016T    DEF     160      58.333333
14  07-Sep-2016T    DEF     150     105.000000
15  08-Sep-2016T    DEF       3     104.333333

旧答案:

In [28]: df.groupby('Client').rolling(3, min_periods=1, center=False).mean()
Out[28]:
                   Date Client          Value
Client
ABC    0   01-Sep-2016T    ABC  160000.000000
       1   02-Sep-2016T    ABC  155000.000000
       2   03-Sep-2016T    ABC  166666.666667
       3   04-Sep-2016T    ABC  180000.000000
       4   05-Sep-2016T    ABC  176666.666667
       5   06-Sep-2016T    ABC  153333.333333
       6   07-Sep-2016T    ABC  148333.333333
       7   08-Sep-2016T    ABC  141333.333333
DEF    8   01-Sep-2016T    DEF     200.000000
       9   02-Sep-2016T    DEF     150.000000
       10  03-Sep-2016T    DEF     150.000000
       11  04-Sep-2016T    DEF      86.666667
       12  05-Sep-2016T    DEF      55.000000
       13  06-Sep-2016T    DEF      58.333333
       14  07-Sep-2016T    DEF     105.000000
       15  08-Sep-2016T    DEF     104.333333

或:

In [31]: df.groupby('Client', as_index=False).rolling(3, min_periods=1, center=False).mean().reset_index(drop=True)
Out[31]:
            Date Client          Value
0   01-Sep-2016T    ABC  160000.000000
1   02-Sep-2016T    ABC  155000.000000
2   03-Sep-2016T    ABC  166666.666667
3   04-Sep-2016T    ABC  180000.000000
4   05-Sep-2016T    ABC  176666.666667
5   06-Sep-2016T    ABC  153333.333333
6   07-Sep-2016T    ABC  148333.333333
7   08-Sep-2016T    ABC  141333.333333
8   01-Sep-2016T    DEF     200.000000
9   02-Sep-2016T    DEF     150.000000
10  03-Sep-2016T    DEF     150.000000
11  04-Sep-2016T    DEF      86.666667
12  05-Sep-2016T    DEF      55.000000
13  06-Sep-2016T    DEF      58.333333
14  07-Sep-2016T    DEF     105.000000
15  08-Sep-2016T    DEF     104.333333