首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python: numpy.corrcoef内存错误

Python: numpy.corrcoef内存错误
EN

Stack Overflow用户
提问于 2014-07-12 21:31:36
回答 1查看 3.9K关注 0票数 3

我试图计算从文本中读取的大量数据之间的相关性。对于非常大的数据集,程序会产生内存错误。谁能告诉我怎么纠正这个问题吗?谢谢

以下是我的代码:

代码语言:javascript
运行
复制
enter code here

import numpy
from numpy  import *
from array import *
from decimal import *
import sys

Threshold = 0.8;
TopMostData = 10;

FileName = sys.argv[1]

File = open(FileName,'r')

SignalData = numpy.empty((1, 128));
SignalData[:][:] = 0;

for line in File:

    TempLine = line.split();
    TempInt = [float(i) for i in TempLine]
    SignalData = vstack((SignalData,TempInt))

del TempLine;
del TempInt;

File.close();

TempData = SignalData;
SignalData = SignalData[1:,:]
SignalData = SignalData[:,65:128]

print "File Read | Data Stored" + " | Total Lines: " + str(len(SignalData))

CorrelationData = numpy.corrcoef(SignalData)

以下是错误:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "Corelation.py", line 36, in <module>
    CorrelationData = numpy.corrcoef(SignalData)
  File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 1824, in corrcoef
    return c/sqrt(multiply.outer(d, d))
MemoryError
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-13 20:23:50

如注释所示,内存不足。如果因为使用32位Python而发生这种情况,那么即使下面的方法也会失败。但是对于64位Python和不太大的RAM情况,我们可以做很多事情,因为计算相关性是容易的,因为您同时只需要内存中的两行。

因此,您可以将输入分成1000行块,然后生成的1000 x 1000矩阵很容易保存在内存中。然后,您可以将结果组装到不一定在RAM中的大输出矩阵中。我推荐这种方法,即使您有大量的RAM,因为这是更多的内存友好。相关系数的计算并不是一种操作,如果输入可以保持在RAM中,那么快速随机访问将有很大帮助。

不幸的是,numpy.corrcoef不能自动完成这一任务,我们将不得不自己计算相关系数。幸运的是,这并不像听起来那么难。

类似于这样的东西:

代码语言:javascript
运行
复制
import numpy as np

# number of rows in one chunk
SPLITROWS = 1000

# the big table, which is usually bigger
bigdata = numpy.random.random((27000, 128))

numrows = bigdata.shape[0]

# subtract means form the input data
bigdata -= np.mean(bigdata, axis=1)[:,None]

# normalize the data
bigdata /= np.sqrt(np.sum(bigdata*bigdata, axis=1))[:,None]

# reserve the resulting table onto HDD
res = np.memmap("/tmp/mydata.dat", 'float64', mode='w+', shape=(numrows, numrows))

for r in range(0, numrows, SPLITROWS):
    for c in range(0, numrows, SPLITROWS):
        r1 = r + SPLITROWS
        c1 = c + SPLITROWS
        chunk1 = bigdata[r:r1]
        chunk2 = bigdata[c:c1]
        res[r:r1, c:c1] = np.dot(chunk1, chunk2.T)

一些注意事项:

  • 以上代码在np.corrcoef(bigdata)上进行了测试。
  • 如果您有复杂的值,则需要创建一个复杂的输出数组res,并接受chunk2.T的复杂共轭
  • 代码将bigdata用于维护性能和最小化内存使用;如果需要保留它,请复制一份

上面的代码在我的机器上运行大约需要85秒,但是数据大部分都是在RAM中运行的,而且我有一个SSD磁盘。该算法按照这样的顺序编码,以避免对HDD的太随机访问,即访问是合理的顺序。相比之下,即使您有大量内存,非memory标准版本也不会显着地加快速度。(实际上,这在我的案子中花了很多时间,但我想我用完了我的16 GiB,然后发生了大量的交换。)

通过省略矩阵的一半,可以使实际的计算更快,因为res.T == res。在实践中,您可以省略c > r中的所有块,然后在稍后映射它们。另一方面,性能很可能受到HDD性能的限制,因此其他优化不一定带来更快的速度。

当然,这种方法很容易并行,因为块计算是完全独立的。而且,所映射的数组可以很容易地在线程之间共享。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24717513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档