pandas按组计算的移动平均数错误
pandas moving average by group calculation is wrong
我的数据框 priceDF 是这样开始的:
Date symbol Close
0 2000-01-03 HELN.SW 28.28
1 2000-01-04 HELN.SW 27.50
2 2000-01-05 HELN.SW 26.71
3 2000-01-06 HELN.SW 27.16
4 2000-01-07 HELN.SW 27.50
要计算收盘价的移动平均线,我按交易品种分组:
priceDF['avg'] = priceDF.groupby('symbol')'Close'].rolling(3).mean().reset_index(drop=True)
我得到:
Date symbol Close avg
0 2000-01-03 HELN.SW 28.28 NaN
1 2000-01-04 HELN.SW 27.50 NaN
2 2000-01-05 HELN.SW 26.71 12.537398
3 2000-01-06 HELN.SW 27.16 12.022164
4 2000-01-07 HELN.SW 27.50 11.922733
在第 2 行中,我想要 avg = 27.50,即第 0 行到第 2 行中收盘价的平均值。
我误解了什么?
我很确定这是这里使用 reset_index
的问题,与多个组一起使用。让我们考虑一个稍微扩展的例子:
from io import StringIO
data = StringIO(
'''
Date symbol Close
0 2000-01-03 HELN.SW 28.28
1 2000-01-04 HELN.SW 27.50
2 2000-01-05 HELN.SW 26.71
3 2000-01-06 HELN.SW 27.16
4 2000-01-07 HELN.SW 27.50
5 2000-01-07 AAAA.SW 30.00
''')
df = pd.read_csv(data, sep = '\s+', index_col=0)
(我们已将 AAAA.SW 添加到列表中)
现在这个:
df.groupby('symbol')['Close'].rolling(3).mean()
产生合理的数字(因为 AAAA 只有一个日期,我们期望 NaN:
symbol
AAAA.SW 5 NaN
HELN.SW 0 NaN
1 NaN
2 27.496667
3 27.123333
4 27.123333
Name: Close, dtype: float64
但是这个:
df.groupby('symbol')['Close'].rolling(3).mean().reset_index(drop=True)
产生错误的索引
0 NaN
1 NaN
2 NaN
3 27.496667
4 27.123333
5 27.123333
Name: Close, dtype: float64
并且当放入原始 df 时最终出现在错误的行中:
df['avg'] = df.groupby('symbol')['Close'].rolling(3).mean().reset_index(drop=True)
df
产生
Date symbol Close avg
0 2000-01-03 HELN.SW 28.28 NaN
1 2000-01-04 HELN.SW 27.50 NaN
2 2000-01-05 HELN.SW 26.71 NaN
3 2000-01-06 HELN.SW 27.16 27.496667
4 2000-01-07 HELN.SW 27.50 27.123333
5 2000-01-07 AAAA.SW 30.00 27.123333
一个解决方案是在每个组内进行分配,如下所示:
df.groupby('symbol').apply(lambda g: g.assign(avg = g['Close'].rolling(3).mean())).reset_index(drop=True)
所以我们得到
Date symbol Close avg
0 2000-01-07 AAAA.SW 30.00 NaN
1 2000-01-03 HELN.SW 28.28 NaN
2 2000-01-04 HELN.SW 27.50 NaN
3 2000-01-05 HELN.SW 26.71 27.496667
4 2000-01-06 HELN.SW 27.16 27.123333
5 2000-01-07 HELN.SW 27.50 27.123333
我的数据框 priceDF 是这样开始的:
Date symbol Close
0 2000-01-03 HELN.SW 28.28
1 2000-01-04 HELN.SW 27.50
2 2000-01-05 HELN.SW 26.71
3 2000-01-06 HELN.SW 27.16
4 2000-01-07 HELN.SW 27.50
要计算收盘价的移动平均线,我按交易品种分组:
priceDF['avg'] = priceDF.groupby('symbol')'Close'].rolling(3).mean().reset_index(drop=True)
我得到:
Date symbol Close avg
0 2000-01-03 HELN.SW 28.28 NaN
1 2000-01-04 HELN.SW 27.50 NaN
2 2000-01-05 HELN.SW 26.71 12.537398
3 2000-01-06 HELN.SW 27.16 12.022164
4 2000-01-07 HELN.SW 27.50 11.922733
在第 2 行中,我想要 avg = 27.50,即第 0 行到第 2 行中收盘价的平均值。 我误解了什么?
我很确定这是这里使用 reset_index
的问题,与多个组一起使用。让我们考虑一个稍微扩展的例子:
from io import StringIO
data = StringIO(
'''
Date symbol Close
0 2000-01-03 HELN.SW 28.28
1 2000-01-04 HELN.SW 27.50
2 2000-01-05 HELN.SW 26.71
3 2000-01-06 HELN.SW 27.16
4 2000-01-07 HELN.SW 27.50
5 2000-01-07 AAAA.SW 30.00
''')
df = pd.read_csv(data, sep = '\s+', index_col=0)
(我们已将 AAAA.SW 添加到列表中)
现在这个:
df.groupby('symbol')['Close'].rolling(3).mean()
产生合理的数字(因为 AAAA 只有一个日期,我们期望 NaN:
symbol
AAAA.SW 5 NaN
HELN.SW 0 NaN
1 NaN
2 27.496667
3 27.123333
4 27.123333
Name: Close, dtype: float64
但是这个:
df.groupby('symbol')['Close'].rolling(3).mean().reset_index(drop=True)
产生错误的索引
0 NaN
1 NaN
2 NaN
3 27.496667
4 27.123333
5 27.123333
Name: Close, dtype: float64
并且当放入原始 df 时最终出现在错误的行中:
df['avg'] = df.groupby('symbol')['Close'].rolling(3).mean().reset_index(drop=True)
df
产生
Date symbol Close avg
0 2000-01-03 HELN.SW 28.28 NaN
1 2000-01-04 HELN.SW 27.50 NaN
2 2000-01-05 HELN.SW 26.71 NaN
3 2000-01-06 HELN.SW 27.16 27.496667
4 2000-01-07 HELN.SW 27.50 27.123333
5 2000-01-07 AAAA.SW 30.00 27.123333
一个解决方案是在每个组内进行分配,如下所示:
df.groupby('symbol').apply(lambda g: g.assign(avg = g['Close'].rolling(3).mean())).reset_index(drop=True)
所以我们得到
Date symbol Close avg
0 2000-01-07 AAAA.SW 30.00 NaN
1 2000-01-03 HELN.SW 28.28 NaN
2 2000-01-04 HELN.SW 27.50 NaN
3 2000-01-05 HELN.SW 26.71 27.496667
4 2000-01-06 HELN.SW 27.16 27.123333
5 2000-01-07 HELN.SW 27.50 27.123333