gpt4 book ai didi

python - 两个 Pandas 数据帧之间的快速斯 PIL 曼相关性

转载 作者:行者123 更新时间:2023-12-03 20:24:13 26 4
gpt4 key购买 nike

我想将 spearman 相关性应用于具有相同列数的两个 pandas 数据帧(每对行的相关性)。

我的目标是计算每对行 (r, s) 之间的 spearman 相关分布,其中 r 是第一个数据帧中的一行,s 是第二个数据帧中的一行。

我知道之前已经回答过类似的问题(参见 this)。但是,这个问题有所不同,因为我想将第一个数据帧的每一行与第二个数据帧的所有行进行比较。此外,这是计算密集型的,并且由于我的数据量大需要几个小时。我想并行化它并可能重写它以加快速度。

我尝试使用 numba 但不幸的是它失败了(与 this 类似的问题),因为它似乎无法识别 scipy spearmanr .我的代码如下:

def corr(a, b):
dist = []
for i in range(a.shape[0]):
for j in range(b.shape[0]):
dist += [spearmanr(a.iloc[i, :], b.iloc[j, :])[0]]
return dist

最佳答案

新答案

from numba import njit
import pandas as pd
import numpy as np

@njit
def mean1(a):
n = len(a)
b = np.empty(n)
for i in range(n):
b[i] = a[i].mean()
return b

@njit
def std1(a):
n = len(a)
b = np.empty(n)
for i in range(n):
b[i] = a[i].std()
return b

@njit
def c(a, b):
''' Correlation '''
n, k = a.shape
m, k = b.shape

mu_a = mean1(a)
mu_b = mean1(b)
sig_a = std1(a)
sig_b = std1(b)

out = np.empty((n, m))

for i in range(n):
for j in range(m):
out[i, j] = (a[i] - mu_a[i]) @ (b[j] - mu_b[j]) / k / sig_a[i] / sig_b[j]

return out

r = df_test.rank(1).values
df_test.T.corr('spearman') == c(r, r)

旧答案

进行 Spearman Rank 相关只是对排名进行相关。

排名

我们可以利用 argsort 来获得排名。虽然 argsortargsort 确实为我们提供了排名,但我们可以通过切片分配将自己限制为一种排序。

def rank(a):
i, j = np.meshgrid(*map(np.arange, a.shape), indexing='ij')

s = a.argsort(1)
out = np.empty_like(s)
out[i, s] = j

return out

相关性

在关联秩的情况下,均值和标准差都是由数组第二维的大小预先确定的。

你可以在没有 numba 的情况下完成同样的事情,但我假设你想要它。

from numba import njit

@njit
def c(a, b):
n, k = a.shape
m, k = b.shape

mu = (k - 1) / 2
sig = ((k - 1) * (k + 1) / 12) ** .5

out = np.empty((n, m))

a = a - mu
b = b - mu

for i in range(n):
for j in range(m):
out[i, j] = a[i] @ b[j] / k / sig ** 2

return out

对于后代,我们可以完全避免内部循环,但这可能会出现内存问题。

@njit
def c1(a, b):
n, k = a.shape
m, k = b.shape

mu = (k - 1) / 2
sig = ((k - 1) * (k + 1) / 12) ** .5

a = a - mu
b = b - mu

return a @ b.T / k / sig ** 2

演示

np.random.seed([3, 1415])

a = np.random.randn(2, 10)
b = np.random.randn(2, 10)

rank_a = rank(a)
rank_b = rank(b)

c(rank_a, rank_b)

array([[0.32121212, 0.01818182],
[0.13939394, 0.55151515]])

如果您使用的是 DataFrame

da = pd.DataFrame(a)
db = pd.DataFrame(b)

pd.DataFrame(c(rank(da.values), rank(db.values)), da.index, db.index)


0 1
0 0.321212 0.018182
1 0.139394 0.551515

验证

我们可以使用 pandas.DataFrame.corr

进行快速验证
pd.DataFrame(a.T).corr('spearman') == c(rank_a, rank_a)

0 1
0 True True
1 True True

关于python - 两个 Pandas 数据帧之间的快速斯 PIL 曼相关性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52371329/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com