熊猫计算错了吗?

jer*_*imo 8 moving-average exponential pandas

当试图从数据框中的财务数据计算指数移动平均线(EMA)时,似乎Pandas的ewm方法是不正确的.

基本知识在以下链接中有详细解释:http://stockcharts.com/school/doku.php?id = chart_school:technical_indicators: move_averages

在进行Pandas解释时,采用的方法如下(使用"adjust"参数为False):

   weighted_average[0] = arg[0];
   weighted_average[i] = (1-alpha) * weighted_average[i-1] + alpha * arg[i]
Run Code Online (Sandbox Code Playgroud)

这在我看来是不正确的."arg"应该是(例如)结束值,但是,arg [0]是第一个平均值(即所选时段长度的第一个数据系列的简单平均值),但不是第一个结束值.因此,arg [0]和arg [i]永远不会来自相同的数据.使用"min_periods"参数似乎无法解决此问题.

任何人都可以解释一下(如果)Pandas如何用于正确计算数据的EMA?

chr*_*isb 11

有几种方法可以初始化指数移动平均线,所以我不会说熊猫做错了,只是不同.

这将是一种计算它的方式:

In [20]: s.head()
Out[20]: 
0    22.27
1    22.19
2    22.08
3    22.17
4    22.18
Name: Price, dtype: float64

In [21]: span = 10

In [22]: sma = s.rolling(window=span, min_periods=span).mean()[:span]

In [24]: rest = s[span:]

In [25]: pd.concat([sma, rest]).ewm(span=span, adjust=False).mean()
Out[25]: 
0           NaN
1           NaN
2           NaN
3           NaN
4           NaN
5           NaN
6           NaN
7           NaN
8           NaN
9     22.221000
10    22.208091
11    22.241165
12    22.266408
13    22.328879
14    22.516356
15    22.795200
16    22.968800
17    23.125382
18    23.275312
19    23.339801
20    23.427110
21    23.507635
22    23.533520
23    23.471062
24    23.403596
25    23.390215
26    23.261085
27    23.231797
28    23.080561
29    22.915004
Name: Price, dtype: float64
Run Code Online (Sandbox Code Playgroud)


小智 8

以下是 Pandas 如何计算调整后和未调整 ewm 的示例:

name = 'closing'
series = pd.Series([1, 2, 3, 5, 8, 13, 21, 34], name=name).to_frame()
period = 4
alpha = 2/(1+period)

series[name+'_ewma'] = np.nan
series.loc[0, name+'_ewma'] = series[name].iloc[0]

series[name+'_ewma_adjust'] = np.nan
series.loc[0, name+'_ewma_adjust'] = series[name].iloc[0]

for i in range(1, len(series)):
    series.loc[i, name+'_ewma'] = (1-alpha) * series.loc[i-1, name+'_ewma'] + alpha * series.loc[i, name]

    ajusted_weights = np.array([(1-alpha)**(i-t) for t in range(i+1)])
    series.loc[i, name+'_ewma_adjust'] = np.sum(series.iloc[0:i+1][name].values * ajusted_weights) / ajusted_weights.sum()

print(series)
print("diff adjusted=False -> ", np.sum(series[name+'_ewma'] - series[name].ewm(span=period, adjust=False).mean()))
print("diff adjusted=True -> ", np.sum(series[name+'_ewma_adjust'] - series[name].ewm(span=period, adjust=True).mean()))
Run Code Online (Sandbox Code Playgroud)

数学公式可以在https://github.com/pandas-dev/pandas/issues/8861找到


ark*_*har 6

您可以span在Pandas ewm函数中使用alpha或系数()计算EWMA 。

式使用阿尔法:(1 - alpha) * previous_val + alpha * current_val 其中alpha = 1 / period

使用系数的公式:((current_val - previous_val) * coeff) + previous_val 其中coeff = 2 / (period + 1)

这是如何使用熊猫来计算上述公式的方法:

con = pd.concat([df[:period][base].rolling(window=period).mean(), df[period:][base]])

if (alpha == True):
    df[target] = con.ewm(alpha=1 / period, adjust=False).mean()
else:
    df[target] = con.ewm(span=period, adjust=False).mean()
Run Code Online (Sandbox Code Playgroud)

  • 为模棱两可而道歉。`base` 是 DataFrame 中要计算 EWMA 的基础列。 (2认同)

小智 5

如果您正在计算 ewm 的 ewm(如 MACD 公式),您将得到不好的结果,因为第二个及后续的 ewm 将使用以 0 开头并以句点结尾的索引。我使用以下解决方案。

sma = df['Close'].rolling(period, min_periods=period).mean()
#this variable is used to shift index by non null start minus period
idx_start = sma.isna().sum() + 1 - period
idx_end = idx_start + period
sma = sma[idx_start: idx_end]
rest = df[item][idx_end:]
ema = pd.concat([sma, rest]).ewm(span=period, adjust=False).mean()
Run Code Online (Sandbox Code Playgroud)