Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python生成滚动窗口以计算相关性_Python_Pandas_Numpy - Fatal编程技术网

Python生成滚动窗口以计算相关性

Python生成滚动窗口以计算相关性,python,pandas,numpy,Python,Pandas,Numpy,我有一个大熊猫数据框(97165行和2列),我想计算并保存每100行这些列之间的相关性,我想这样做: 第1个相关性-->从0到100的行-->corr=0.265 第二个相关性-->从1到101的行-->corr=0.279 第三个相关性-->行从2到102-->corr=0.287 每个值都必须存储并在绘图中显示,所以我必须将所有这些值保存在列表或类似的东西中 我一直在阅读有关滚动窗口的熊猫文档 但我什么都没能做到。 我尝试生成一个简单的循环以获得一些结果,但我遇到了内存问题,我尝试的代码是:

我有一个大熊猫数据框(97165行和2列),我想计算并保存每100行这些列之间的相关性,我想这样做:

第1个相关性-->从0到100的行-->corr=0.265

第二个相关性-->从1到101的行-->corr=0.279

第三个相关性-->行从2到102-->corr=0.287

每个值都必须存储并在绘图中显示,所以我必须将所有这些值保存在列表或类似的东西中

我一直在阅读有关滚动窗口的熊猫文档 但我什么都没能做到。 我尝试生成一个简单的循环以获得一些结果,但我遇到了内存问题,我尝试的代码是:

lcl = 100
a = []
for i in range(len(tabla)):

    x = tabla.iloc[i:lcl, [0]] 
    y = tabla.iloc[i:lcl, [1]]
    z = x['2015_Avion'].corr(y['2015_Hotel'])
    a.append(z) 
    lcl += 1

有什么建议吗?

我们可以通过处理阵列数据来优化内存和性能

方法#1

首先,让我们使用数组解决方案来获得两个
1D
数组之间对应元素的相关系数。这将基本上受到启发,看起来像这样-

def corrcoeff_1d(A,B):
    # Rowwise mean of input arrays & subtract from input arrays themeselves
    A_mA = A - A.mean(-1,keepdims=1)
    B_mB = B - B.mean(-1,keepdims=1)

    # Sum of squares
    ssA = np.einsum('i,i->',A_mA, A_mA)
    ssB = np.einsum('i,i->',B_mB, B_mB)

    # Finally get corr coeff
    return np.einsum('i,i->',A_mA,B_mB)/np.sqrt(ssA*ssB)
现在,要使用它,请在数组数据上使用相同的循环-

lcl = 100
ar = tabla.values
N = len(ar)
out = np.zeros(N)
for i in range(N):
    out[i] = corrcoeff_1d(ar[i:i+lcl,0], ar[i:i+lcl,1])
我们可以通过预先计算滚动平均值来进一步优化性能,滚动平均值用于使用卷积计算
corrcoff\u 1d
中的
A_mA
,但首先让我们排除内存错误

方法#2

这是一种几乎矢量化的方法,因为我们将矢量化大多数迭代,除了末尾没有适当窗口长度的剩余切片。循环计数将从
97165
减少到
lcl-1
,即仅
99

lcl = 100
ar = tabla.values
N = len(ar)
out = np.zeros(N)

col0_win = strided_app(ar[:,0],lcl,S=1)
col1_win = strided_app(ar[:,1],lcl,S=1)
vectorized_out = corr2_coeff_rowwise(col0_win, col1_win)
M = len(vectorized_out)
out[:M] = vectorized_out

for i in range(M,N):
    out[i] = corrcoeff_1d(ar[i:i+lcl,0], ar[i:i+lcl,1])
辅助函数-

# https://stackoverflow.com/a/40085052/ @ Divakar
def strided_app(a, L, S ):  # Window len = L, Stride len/stepsize = S
    nrows = ((a.size-L)//S)+1
    n = a.strides[0]
    return np.lib.stride_tricks.as_strided(a, shape=(nrows,L), strides=(S*n,n))

# https://stackoverflow.com/a/41703623/ @Divakar
def corr2_coeff_rowwise(A,B):
    # Rowwise mean of input arrays & subtract from input arrays themeselves
    A_mA = A - A.mean(-1,keepdims=1)
    B_mB = B - B.mean(-1,keepdims=1)

    # Sum of squares across rows
    ssA = np.einsum('ij,ij->i',A_mA, A_mA)
    ssB = np.einsum('ij,ij->i',B_mB, B_mB)

    # Finally get corr coeff
    return np.einsum('ij,ij->i',A_mA,B_mB)/np.sqrt(ssA*ssB)

NaN填充数据的相关性

下面列出了用于计算一维阵列和行相关值之间相关性的基于Pandas的相关计算的NumPy解决方案

1) 两个一维阵列之间的标量相关值-

def nancorrcoeff_1d(A,B):
    # Get combined mask
    comb_mask = ~(np.isnan(A) & ~np.isnan(B))
    count = comb_mask.sum()

    # Rowwise mean of input arrays & subtract from input arrays themeselves
    A_mA = A - np.nansum(A * comb_mask,-1,keepdims=1)/count
    B_mB = B - np.nansum(B * comb_mask,-1,keepdims=1)/count

    # Replace NaNs with zeros, so that later summations could be computed    
    A_mA[~comb_mask] = 0
    B_mB[~comb_mask] = 0

    ssA = np.inner(A_mA,A_mA)
    ssB = np.inner(B_mB,B_mB)

    # Finally get corr coeff
    return np.inner(A_mA,B_mB)/np.sqrt(ssA*ssB)
2) 两个
2D
数组
(m,n)
之间的行相关,为我们提供一个
1D
形状数组
(m,)
-


您提到尝试
滚动
。这到底出了什么问题?这对我很有用:

my_res = tabla['2015_Avion'].rolling(100).corr(tabla['2015_Hotel'])

my_res
将具有
NaN
值,直到其
100
th值,因此
my_res[99]
应该是两列的行
0
和行
99
元素之间的相关性,这将由仅应用于子集的
pandas
corr
函数返回
my_res[100]
是行
1
和行
100
元素之间的相关性。

输入数据框中有什么?用最少的代表性数据制作样本?另外,您在哪一步得到内存错误?排序的整数值大多数输出值是nan或0,在我的表中只有0到10之间的整数值。因此我不明白为什么我得到nan/0值。您是从某种csv读取的吗?是否可能某些值具有转义字符或导致问题的非ascii字符?我希望它会抛出一个错误,但这取决于corr()的工作方式。我现在无法使用一些随机整数重新创建问题。我使用read_pickle读取文件,格式是bz2。我查看了数据集,但没有发现任何奇怪的地方。我没有使用python中的read_pickle或bz2的经验。尝试打印(repr())某些值,以检查是否出现任何奇怪的情况(print()可能无法捕获转义字符等)-例如,在窗口中提供NaN相关性的所有值上。如果my和Divakar的解决方案都提供0/NaN,我强烈建议查看数据本身-问题几乎肯定存在。你可以自己检查,也可以根据Divakar的建议发布一个示例。谢谢你的帮助,这很好,但我遇到了与其他方法相同的问题,前77个值很好,但之后所有值都是0或nan。idk为什么,但这一切都在发生solutions@WinterZ正如我在前面的评论中所说-。有一个bz2格式的样本,在我所有的方法中都包含10k行,就像在你的方法中一样,因为corr行77我得到了nan值…@WinterZ So?这两种解决方案现在都起作用了吗?问题是我对数据进行了排序,所以有很多重复值。您的解决方案非常好,但在我的例子中,我得到了nan值,因为这行代码:A_mA=A-A.mean(-1,keepdims=1),例如,所有用3填充的向量使A_mA等于0,并且当该值为0时,相关性公式不起作用。多谢各位!
my_res = tabla['2015_Avion'].rolling(100).corr(tabla['2015_Hotel'])