代码之家  ›  专栏  ›  技术社区  ›  Erlinska

熊猫指数加权移动平均问题

  •  0
  • Erlinska  · 技术社区  · 8 年前

    我在用熊猫计算指数加权移动平均值(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
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   Erlinska    8 年前

    解决了这个问题,我只是个白痴。

    我使用的公式是: df_bis = alpha*m1["open"].shift(1) + (1-alpha)*df.shift(1)

    但价格不应该在这里变动,正确的计算方法是:

    df_bis = alpha*m1["open"] + (1-alpha)*df.shift(1)
    

    这将产生:

    diff_array
    Out[24]: 
    DateTime
    2015-01-04 22:09:00    0.0
    2015-01-04 22:10:00    0.0
    2015-01-04 22:11:00    0.0
    2015-01-04 22:12:00    0.0
    2015-01-04 22:13:00    0.0
    2015-01-04 22:14:00    0.0
    2015-01-04 22:15:00    0.0
    2015-01-04 22:16:00    0.0
    2015-01-04 22:17:00    0.0
    2015-01-04 22:18:00    0.0
    2015-01-04 22:19:00    0.0
    2015-01-04 22:20:00    0.0