使用 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
这是我拥有的非常小的时间序列数据子集:
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