Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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_Arrays_Numpy_Statistics_Scipy - Fatal编程技术网

Python 有没有更快的方法获得同样的结果?

Python 有没有更快的方法获得同样的结果?,python,arrays,numpy,statistics,scipy,Python,Arrays,Numpy,Statistics,Scipy,我有两个给定的数组:x和y。我想计算两个数组之间的相关系数,如下所示: import numpy as np from scipy.stats import pearsonr x = np.array([[[1,2,3,4], [5,6,7,8]], [[11,22,23,24], [25,26,27,28]]]) i,j,k = x.shape y = np.array([[[31,32,33,34

我有两个给定的数组:x和y。我想计算两个数组之间的相关系数,如下所示:

import numpy as np
from scipy.stats import pearsonr

x = np.array([[[1,2,3,4],
               [5,6,7,8]],
              [[11,22,23,24],
               [25,26,27,28]]])


i,j,k = x.shape

y = np.array([[[31,32,33,34],
               [35,36,37,38]],
              [[41,42,43,44],
               [45,46,47,48]]])



xx = np.row_stack(np.dstack(x))
yy = np.row_stack(np.dstack(y))

results = []

for a, b in zip(xx,yy):
    r_sq, p_val = pearsonr(a, b)
    results.append(r_sq)

results = np.array(results).reshape(j,k)

print results

[[ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]]
答案是正确的。但是,我想知道是否有更好、更快的方法可以使用numpy和/或scipy完成此操作。

另一种方法(不一定更好)是:

另一个当前线程正在讨论使用列表理解来迭代数组的值:

正如这里所讨论的,另一种方法是初始化
结果
,并在迭代过程中填充值。对于真正大型的案例,这可能更快,但对于规模较小的案例,这

np.array([... for .. in ...]) 
这是合理的

更深层次的问题是,
pearsonr
或其他替代方法是否可以计算多对而不是一对的这种相关性。这可能需要研究
pearsonr
的内部结构,或
stats
中的其他函数

这是对统计数据进行矢量化的第一个切入点。pearsonr:

def pearsonr2(a,b):
    # stats.pearsonr adapted for
    # x and y are (N,2) arrays
    n = x.shape[1]
    mx = x.mean(1)
    my = y.mean(1)
    xm, ym = x-mx[:,None], y-my[:,None]
    r_num = np.add.reduce(xm * ym, 1)
    r_den = np.sqrt(stats.ss(xm,1) * stats.ss(ym,1))
    r = r_num / r_den
    r = np.clip(r, -1.0, 1.0)
    return r

print pearsonr2(xx,yy)
它与您的情况相匹配,尽管这些测试值并不能真正实现该功能。我只是使用了
pearsonr
代码,在大多数行中添加了
axis=1
参数,并确保一切都正常运行。
prob
步骤可以包含一些布尔掩蔽

(如果需要,我可以将
stats.pearsonr
代码添加到我的答案中)


此版本将采用任何维度
a
b
(只要它们相同),并沿指定轴进行
pearsonr
计算。无需整形

def pearsonr_flex(a,b, axis=1):
    # stats.pearsonr adapted for
    # x and y are (N,2) arrays
    n = x.shape[axis]
    mx = x.mean(axis, keepdims=True)
    my = y.mean(axis, keepdims=True)
    xm, ym = x-mx, y-my
    r_num = np.add.reduce(xm * ym, axis)
    r_den = np.sqrt(stats.ss(xm, axis) * stats.ss(ym, axis))
    r = r_num / r_den
    r = np.clip(r, -1.0, 1.0)
    return r

pearsonr_flex(xx, yy, 1)
preasonr_flex(x, y, 0)

对于-->来说,一个更好的问题可能是计算数组x的元素[1,11]和数组y的元素[31,41]之间的相关系数,依此类推……这是否真的在
codereview
上更好,这是有争议的。这是一个
numpy
矢量化的问题,在
Stack
上有很多这样的问题。如果主题行是“如何将其矢量化”,您是否建议将其移动到CR?是最近关于
numpy
通过矢量化加速的另一个讨论。当x和y的形状分别为(3,3,5)和(3,3,5)时,我如何修改您的矢量化函数。我建议了两种概括维度的方法。感谢您的更新。def pearsonr2不能集成到def pearsonr_m中,以便单个函数可以应用于任何形状,即(第一种情况下为2,2,4)或(另一种情况下为3,3,5),考虑到pearson应用于最后一个维度。我重写了我的函数,以处理任何形状,并在任何轴上进行关联。比你做得多,这太棒了。
def pearsonr_flex(a,b, axis=1):
    # stats.pearsonr adapted for
    # x and y are (N,2) arrays
    n = x.shape[axis]
    mx = x.mean(axis, keepdims=True)
    my = y.mean(axis, keepdims=True)
    xm, ym = x-mx, y-my
    r_num = np.add.reduce(xm * ym, axis)
    r_den = np.sqrt(stats.ss(xm, axis) * stats.ss(ym, axis))
    r = r_num / r_den
    r = np.clip(r, -1.0, 1.0)
    return r

pearsonr_flex(xx, yy, 1)
preasonr_flex(x, y, 0)