我试图计算从文本中读取的大量数据之间的相关性。对于极大的数据集,程序会给出内存错误。任何人都可以告诉我如何纠正这个问题。感谢
以下是我的代码:
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)
以下是错误:
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
答案 0 :(得分:8)
评论显示,内存不足。如果发生这种情况是因为您使用的是32位Python,那么即使是下面的方法也会失败。但是对于64位Python和不那么多RAM的情况,我们可以做很多事情,因为计算相关性很容易分段完成,因为你只需要同时在内存中有两行。
因此,您可以将输入拆分为1000行块,然后生成的1000 x 1000矩阵很容易保留在内存中。然后,您可以将结果汇总到大输出矩阵中,该矩阵不一定在RAM中。即使你有很多内存,我也推荐这种方法,因为这对内存更友好。如果输入可以保存在RAM中,则相关系数计算不是快速随机访问会有很大帮助的操作。
不幸的是,numpy.corrcoef
不会自动执行此操作,我们将不得不滚动自己的相关系数计算。幸运的是,这并不像听起来那么难。
这些方面的东西:
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,即访问是合理顺序的。相比之下,即使您拥有大量内存,非memmapped标准版本也不会明显更快。 (实际上,我的情况需要花费更多的时间,但我怀疑我的16 GiB用完了,然后进行了大量的交换。)
通过省略矩阵的一半,您可以更快地进行实际计算,因为res.T == res
。实际上,您可以省略c > r
中的所有块,然后再镜像它们。另一方面,性能很可能受到HDD性能的限制,因此其他优化并不一定会带来更快的速度。
当然,这种方法很容易并行,因为块计算是完全独立的。也可以很容易地在线程之间共享memmapped数组。