我在用熊猫计算指数加权移动平均值(ewma)时遇到了一个小问题:
在这里,我使用pandas函数计算我的价格的9期ewma:
df = m1["open"].ewm(min_periods=9,span=9).mean()
用于计算ewma的公式如下:
ewm(t+1) = alpha * price + (1-alpha) * ewm(t)
具有
alpha = 2/(period+1)
熊猫功能给我的结果似乎不正确,所以我尝试验证它:
df = m1["open"].ewm(min_periods=9,span=9).mean()
alpha = 2/(9+1)
df_bis = alpha*m1["open"].shift(1) + (1-alpha)*df.shift(1)
bol_array = df == df_bis
df
作为pandas函数返回的数据帧,
df_bis
使用df数据和价格的公式。
bol_array
都应该是真的
df公司
和
df\U bis
应该相等。
然而,事实并非如此,这里我随机选取了
bol\U阵列
:
2015-01-09 21:32:00 False
2015-01-09 21:33:00 False
2015-01-09 21:34:00 True
2015-01-09 21:35:00 False
2015-01-09 21:36:00 False
2015-01-09 21:37:00 False
2015-01-09 21:38:00 False
2015-01-09 21:39:00 False
2015-01-09 21:40:00 False
2015-01-09 21:41:00 False
2015-01-09 21:42:00 False
2015-01-09 21:43:00 True
2015-01-09 21:44:00 False
2015-01-09 21:45:00 False
有时,他们是平等的,有时是不平等的。
我在一个特定的时间进行了检查,看看是否存在舍入问题:
m1["open"][15]*alpha + df[15]*(1-alpha)
Out[7]: 1.1931468623934722
df[16]
Out[8]: 1.1930652375329887
结果确实不同,这不是舍入问题(我需要5位数的精度)。
有人知道这里有什么问题吗?
我似乎找不到问题所在。
编辑:
为了看看这是否是一个舍入问题,我添加了一个数组来测量熊猫的
diff_array = df-df_bis
我需要5位数的精度,所以我将这个数组乘以10^5,以便更好地显示差异的大小:
diff_array*10**5
Out[16]:
DateTime
2015-01-04 22:00:00 NaN
2015-01-04 22:01:00 NaN
2015-01-04 22:02:00 NaN
2015-01-04 22:03:00 NaN
2015-01-04 22:04:00 NaN
2015-01-04 22:05:00 NaN
2015-01-04 22:06:00 NaN
2015-01-04 22:07:00 NaN
2015-01-04 22:08:00 NaN
2015-01-04 22:09:00 -2.610024
2015-01-04 22:10:00 -60.325142
2015-01-04 22:11:00 27.044649
2015-01-04 22:12:00 32.072310
2015-01-04 22:13:00 -25.944314
2015-01-04 22:14:00 8.201273
2015-01-04 22:15:00 8.358418
2015-01-04 22:16:00 -8.162486
2015-01-04 22:17:00 -11.381701
2015-01-04 22:18:00 8.610419
2015-01-04 22:19:00 4.862610
2015-01-04 22:20:00 3.875236
2015-01-04 22:21:00 1.659843
这种差异有时非常巨大。
尽管我在寻找5位数的精度,但对我来说,相差10^(-5)或两倍是可以的,但就在第一个值之间,相差高达60*(10^-5),这太大了。
编辑2:
我查看了emw的每个参数,得到了相同的结果,直接指定了对应于9周期ewma的alpha参数,这意味着我的参数确实是正确的。
查看熊猫文档,调整参数默认设置为True:
当adjust为False时,加权平均数递归计算为:
加权平均值[0]=arg[0];加权平均值[i]=(1-alpha)
*
加权平均值(i-1)+α
*
arg[一]。
我将adjust参数设置为False,这应该可以解决问题:
df = m1["open"].ewm(min_periods=9,alpha=0.2,adjust=False).mean()
alpha = 2/(9+1)
df_bis = alpha*m1["open"].shift(1) + (1-alpha)*df.shift(1)
diff_array = df-df_bis
diff_array*10**5
Out[11]:
DateTime
2015-01-04 22:09:00 -5.6
2015-01-04 22:10:00 -56.8
2015-01-04 22:11:00 27.2
2015-01-04 22:12:00 30.4
2015-01-04 22:13:00 -25.8
2015-01-04 22:14:00 8.0
2015-01-04 22:15:00 8.0
2015-01-04 22:16:00 -8.2
2015-01-04 22:17:00 -11.2
2015-01-04 22:18:00 8.6
2015-01-04 22:19:00 4.8
但这并不能解决我的问题。
我找不到任何可以解释这种差异的东西,有人知道为什么会有差异吗?
以下是熊猫公司关于这个主题的文档,我之前使用的公式来自:
http://pandas.pydata.org/pandas-docs/stable/computation.html#exponentially-weighted-windows
我使用的数据非常大,下面是一个示例:
m1["open"]
Out[10]:
DateTime
2015-01-04 22:00:00 1.19548
2015-01-04 22:01:00 1.19388
2015-01-04 22:02:00 1.19102
2015-01-04 22:03:00 1.18826
2015-01-04 22:04:00 1.19085
2015-01-04 22:05:00 1.19257
2015-01-04 22:06:00 1.19270
2015-01-04 22:07:00 1.19350
2015-01-04 22:08:00 1.19427
2015-01-04 22:09:00 1.19399
2015-01-04 22:10:00 1.19115
2015-01-04 22:11:00 1.19251
2015-01-04 22:12:00 1.19403
2015-01-04 22:13:00 1.19274
2015-01-04 22:14:00 1.19314
2015-01-04 22:15:00 1.19354
2015-01-04 22:16:00 1.19313
2015-01-04 22:17:00 1.19257
2015-01-04 22:18:00 1.19300
2015-01-04 22:19:00 1.19324
2015-01-04 22:20:00 1.19343
2015-01-04 22:21:00 1.19351
2015-01-04 22:22:00 1.19353
2015-01-04 22:23:00 1.19376
2015-01-04 22:24:00 1.19408
2015-01-04 22:25:00 1.19370
2015-01-04 22:26:00 1.19381
2015-01-04 22:27:00 1.19439
2015-01-04 22:28:00 1.19435
2015-01-04 22:29:00 1.19419