<p><strong>新解决方案</strong></p>
<p>在查看了Joe Kington的答案之后,我决定查看<code>corrcoef()</code>代码,并从中得到灵感,执行以下实现。</p>
<pre><code>ms = data.mean(axis=1)[(slice(None,None,None),None)]
datam = data - ms
datass = np.sqrt(scipy.stats.ss(datam,axis=1))
for i in xrange(rows):
temp = np.dot(datam[i:],datam[i].T)
rs = temp / (datass[i:]*datass[i])
</code></pre>
<p>每个循环遍历生成第i行和第i行到最后一行之间的皮尔逊系数。它很快。它至少比单独使用<code>corrcoef()</code>快1.5倍,因为它没有多余地计算系数和其他一些东西。它也会更快,并且不会给您50000行矩阵的内存问题,因为然后您可以选择存储每一组r,或者在生成另一组之前处理它们。在不存储任何r的长期代码的情况下,我能够在不到一分钟的时间内将上述代码运行在我相当新的笔记本电脑上的50000 x 10组随机生成的数据上。</p>
<p><strong>旧解决方案</strong></p>
<p>首先,我不建议把r打印到屏幕上。对于100行(10列),打印时的差异为19.79秒,而不使用代码时的差异为0.301秒。如果你愿意的话,只需储存r,以后再使用,或者在寻找一些最大的r的过程中对它们进行一些处理</p>
<p>第二,不必重复计算一些数量,可以节省一些开支。皮尔逊系数是用scipy计算的,它使用一些可以预先计算的量,而不是每次使用行时都计算。另外,您没有使用p值(p值也是由<code>pearsonr()</code>返回的),所以让我们也删除它。使用以下代码:</p>
<pre><code>r = np.zeros((rows,rows))
ms = data.mean(axis=1)
datam = np.zeros_like(data)
for i in xrange(rows):
datam[i] = data[i] - ms[i]
datass = scipy.stats.ss(datam,axis=1)
for i in xrange(rows):
for j in xrange(i,rows):
r_num = np.add.reduce(datam[i]*datam[j])
r_den = np.sqrt(datass[i]*datass[j])
r[i,j] = min((r_num / r_den), 1.0)
</code></pre>
<p>当我删除p值的东西时,我得到的速度比直接的scipy代码快4.8倍-如果我把p值的东西放在里面的话,速度是8.8倍(我使用了10列几百行)。我还检查了它是否给出了相同的结果。这并不是一个很大的进步,但可能会有所帮助。</p>
<p>最终,你会陷入计算(50000)*(50001)/2=1250025000皮尔逊系数的问题(如果我计算正确的话)。太多了。顺便说一下,实际上不需要计算每一行的Pearson系数(它等于1),但这只会节省您计算50000个Pearson系数的时间。使用上面的代码,如果根据我在较小数据集上的结果,您的数据有10列,我预计大约需要4 1/4小时来完成计算。</p>
<p>通过将上述代码转换成Cython或类似的代码,您可以得到一些改进。如果你运气好的话,我想你可能会比直筒子进步10倍。另外,正如pyinthsky所建议的,您可以进行一些多处理。</p>