如何通过numpy获得与pandas.autocorr()相同的结果?

nwsw7zdq  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(84)

我需要使用numpy函数来替换所有的Pandas函数,但是Pandas包没有很好地解释pd.autocorr()是如何实现的。

import numpy as np
import pandas as pd

df = pd.DataFrame.from_dict({'A': np.random.random(20)})
x = df.rolling(5).apply(lambda x: x.autocorr(), raw=True).dropna()
y = []
for i in range(15):
  y.append( np.corrcoeff(df['A'][i:i+5],df['A'][i+1:i+6])[0,1] )
  # np.correlate(df['A'][i:i+5]-df['A'][i:i+5].mean(),df['A'][(1+i):(6+i)]-df['A'][(1+i):(6+i)].mean(),'valid')[0]
  # np.correlate(df['A'][i:i+5]-df['A'][i:i+5].mean(),np.flip(df['A'][(1+i):(6+i)])-df['A'][(1+i):(6+i)].mean(),'valid')[0]

字符串
pd.autocorr()的结果与np.corrcoef()的结果有很大的不同(我也是np.correlate()的结果)。有没有什么方法可以使用numpy only函数来实现与pd.autocorr()相同的reulst?

  • 添加了示例结果--
df['A'] = [0.5314742325906894, 0.7424912257400176, 0.2895649008872213, 0.16967710120380175, 0.5157732179121193, 0.8733423106397956, 0.585705172096987, 0.1387299202733231, 0.18540514459343538, 0.13913104211564564, 0.736937228263526, 0.20944078980434988, 0.2826810751427198, 0.15055686873748197, 0.4159491505728884, 0.07600226975854041, 0.15279939462562298, 0.1405723553409276, 0.8372449734938123, 0.3314986851097367]

x = [0.010637545587524432, 0.03594106077726333, 0.40104877005219836, -0.009106549297130558, 0.4008385963492408, 0.7794761931857483, -0.4182779136016351, -0.2962696925038811, -0.4083361773384266, -0.5244693987698964, -0.5063605533618415, -0.9496936641021706, -0.5303040575891907, -0.42881675192105184, -0.3371366910961831, -0.036231529863559424]

y = [0.11823200733266746, 0.16166841984627847, 0.2033980627120384, 0.2861039403548347, 0.5239653859040245, 0.1602079943122044, -0.3920837265006942, -0.28176746883177917, -0.3604612671108854, -0.5347077109231272, -0.4702461092101919, -0.5287673078857449, -0.4501452367448014, -0.3538574959825232, -0.10013342594129321]

7rfyedvj

7rfyedvj1#

如果我们检查pandas.Series.autocorr的文档,如果您使用默认参数调用该函数,则lag为1,这意味着您需要移动一个元素来计算相关性。
举例来说:

a = np.array([0.25, 0.5, 0.2, -0.05])
s = pd.Series(a)

字符串
为您提供:

0.1035526330902407


使用np.corrcoef,您需要将数组切片为两个移位的数组:

np.corrcoef(a[:-1], a[1:])[0, 1]


这给了你同样的结果:

0.1035526330902407


所以在你的例子中,代码应该是这样的:

W = 5 # Window size
nrows = len(df) - W + 1 # number of elemnets after rolling
lag=1
y = []
for i in range(nrows):
    y.append(np.corrcoef(df['A'][i:i+W-lag],df['A'][i+lag:i+W])[0,1])


您将得到与x相同的结果。

gywdnpxw

gywdnpxw2#

pd.autocorr()使用默认值lag=1计算自相关。这意味着它计算数组和移位1的数组之间的相关性。
以下是几种计算方法:

1.遍历并追加每个np.corrcoef

你几乎已经得到了正确的答案,但你只需要偏移lag=1参数:

y = []
for i in range(16):
    y.append(np.corrcoef(df.A[i:i+5][:-1], df.A[i:i+5][1:])[0, 1])

# 3.66 ms ± 98.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

字符串
解决方案是您自己的工作和this answer的混合-这可能会为您提供更多的解释。

2.不带循环,使用np.lib.stride_tricks.sliding_window_view

np.lib.stride_tricks.sliding_window_view允许你创建一个滑动窗口的数组。然后,您可以通过lag参数对其进行切片并计算np.corrcoef,然后获取输出数组后半部分的对角输出:

window = 5
lag = 1

y = np.diagonal(
    np.corrcoef(
        np.lib.stride_tricks.sliding_window_view(df.A, window)[:, :-lag],
        np.lib.stride_tricks.sliding_window_view(df.A, window)[:, lag:])
    [len(df.A) - window + 1:])

# 174 µs ± 2.32 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)


从时间上可以看出,第二种选择要快得多--尽管代码和概念可能更抽象一些。

相关问题