簡體   English   中英

pandas ewm.std 計算

[英]pandas ewm.std calculation

我正在嘗試驗證 Pandas 的 ewm.std 計算,以便我可以為我的代碼實現一步更新。 這是代碼問題的完整描述。

mrt = pd.Series(np.random.randn(1000))
N = 100
a = 2/(1+N)
bias = (2-a)/2/(1-a)
x = mrt.iloc[-2]
ma = mrt.ewm(span=N).mean().iloc[-3]
var = mrt.ewm(span=N).var().iloc[-3]
ans = mrt.ewm(span=N).std().iloc[-2]
print(np.sqrt( bias*(1-a) * (var + a * (x- ma)**2)), ans)

(1.1352524643949702, 1.1436193844674576)

我使用了標准配方。 有人能告訴我為什么這兩個值不應該相同嗎? 即熊貓如何計算指數加權標准?

編輯:在 Julien 回答之后 - 讓我再舉一個用例。 我正在繪制由熊貓計算的 var 的比率,並使用我從熊貓 ewm 協方差的 Cython 代碼推斷出的公式。 這個比率應該是 1。(我猜我的公式有問題,如果有人能指出的話)。

mrt = pd.Series(np.random.randn(1000))

N = 100
a = 2./(1+N)
bias = (2-a)/2./(1-a)
mewma = mrt.ewm(span=N).mean()

var_pandas = mrt.ewm(span=N).var()
var_calculated = bias * (1-a) * (var_pandas.shift(1) + a * (mrt-mewma.shift(1))**2)

(var_calculated/var_pandas).plot()

該圖清楚地顯示了問題。

去除初始值后的比率圖

編輯 2:通過反復試驗,我找到了正確的公式:

var_calculated = (1-a) * (var_pandas.shift(1) + bias * a * (mrt-mewma.shift(1))**2)

但我不相信它應該是正確的! 有人可以解釋一下嗎?

您的問題實際上ewm.var()為熊貓如何計算ewm.var()

In [1]:
(np.sqrt(mrt.ewm(span=span).var()) == mrt.ewm(span=span).std())[1:].value_counts()

Out[1]:
True    999
dtype: int64

所以在你上面的例子中: ans == np.sqrt(mrt.ewm(span=N).var().iloc[-2])

為了研究它如何計算 ewmvar(),它通過使用input_x=input_y=mrt調用emcovinput_x=input_y=mrt


如果我們檢查第一個元素:

mrt.ewm(span=span).var()[:2].values
> array([nan,  0.00555309])

現在,使用 emcov 例程,並將其應用於我們的特定案例:

x0 = mrt.iloc[0]
x1 = mrt.iloc[1]
x2 = mrt.iloc[2]

# mean_x and mean_y are both the same, here we call it y
# This is the same as mrt.ewm(span=span).mean(), I verified that too
y0 = x0
# y1 = mrt.ewm(span=span).mean().iloc[1]
y1 = ((1-alpha)*y0 + x1)/(1+(1-alpha))
#y2 = (((1-alpha)**2+(1-alpha))*y1 + x2) / (1 + (1-alpha) + (1-alpha)**2) 

cov0 = 0

cov1 = (((1-alpha) * (cov0 + ((y0 - y1)**2))) +
                (1 * ((x1 - y1)**2))) / (1 + (1-alpha))

# new_wt = 1, sum_wt0 = (1-alpha), sum_wt2 = (1-alpha)**2
sum_wt = 1+(1-alpha)
sum_wt2 =1+(1-alpha)**2


numerator = sum_wt * sum_wt # (1+(1-alpha))^2 = 1 + 2(1-alpha) + (1-alpha)^2
denominator = numerator - sum_wt2 # # 2*(1-alpha)


print(np.nan,cov1*(numerator / denominator))

>(nan, 0.0055530905712123432)

根據ewm函數的文檔,使用默認標志adjust=True 正如在下面的鏈接中所解釋的,指數加權移動值不是使用遞歸關系計算的,而是使用權重計算的。 這是合理的,特別是對於序列長度很小的情況。

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.ewm.html https://github.com/pandas-dev/pandas/issues/8861

這意味着ewmaewmvar被計算為正常加權平均值和 var ,權重是指數遞減的因素

mrt_array = np.array(mrt.tolist())
M = len(mrt_array)
weights = (1-a)**np.arange(M-1, -1, -1) # This is reverse order to match Series order
ewma = sum(weights * mrt_array) / sum(weights)
bias = sum(weights)**2 / (sum(weights)**2 - sum(weights**2))
ewmvar = bias * sum(weights * (mrt_array - ewma)**2) / sum(weights)
ewmstd = np.sqrt(ewmvar)

謝謝@kosnik以上的回答。 在下面復制粘貼您的代碼並在其上構建以回答此處的問題。 因此計算了整個數據集的指數移動方差和標准偏差。 計算出的值與.ewm()的輸出相匹配。

# Import libraries
import numpy as np
import pandas as pd

# Create DataFrame
mrt = pd.Series(np.random.randn(1000))
df = pd.DataFrame(data=mrt, columns=['data'])


# Initialize 
N = 3 # Span
a = 2./(1+N) # Alpha

# Use .evm() to calculate 'exponential moving variance' directly
var_pandas = df.ewm(span=N).var()
std_pandas = df.ewm(span=N).std()

# Initialize variable
varcalc=[]
stdcalc=[]

# Calculate exponential moving variance
for i in range(0,len(df.data)):

    z = np.array(df.data.iloc[0:i+1].tolist())

    # Get weights: w
    n = len(z)
    w = (1-a)**np.arange(n-1, -1, -1) # This is reverse order to match Series order

    # Calculate exponential moving average
    ewma = np.sum(w * z) / np.sum(w)

    # Calculate bias
    bias = np.sum(w)**2 / (np.sum(w)**2 - np.sum(w**2))

    # Calculate exponential moving variance with bias
    ewmvar = bias * np.sum(w * (z - ewma)**2) / np.sum(w)

    # Calculate standard deviation
    ewmstd = np.sqrt(ewmvar)

    # Append
    varcalc.append(ewmvar)
    stdcalc.append(ewmstd)
    #print('ewmvar:',ewmvar)


#varcalc
df['var_pandas'] = var_pandas
df['varcalc'] = varcalc
df['std_pandas'] = std_pandas
df['stdcalc'] = stdcalc
df

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM