【问题标题】:Memory error: numpy.genfromtxt()内存错误:numpy.genfromtxt()
【发布时间】:2012-07-14 04:23:10
【问题描述】:

我有一个 50,000x5,000 矩阵(浮点)文件。当使用x = np.genfromtxt(readFrom, dtype=float) 将文件加载到内存中时,我收到以下错误消息:

文件“C:\Python27\lib\site-packages\numpy\lib\npyio.py”,第 1583 行, 在 genfromtxt for (i, converter) in enumerate(converters)])
内存错误

我想将整个文件加载到内存中,因为我正在使用 Scipy 计算每个向量之间的欧几里得距离。 dis = scipy.spatial.distance.euclidean(x[row1], x[row2])

是否有任何有效的方法可以将巨大的矩阵文件加载到内存中。

谢谢。

Update:

我设法解决了这个问题。这是我的解决方案。我不确定它是否有效或逻辑正确,但对我来说效果很好:

x = open(readFrom, 'r').readlines()
y = np.asarray([np.array(s.split()).astype('float32') for s in x], dtype=np.float32)
....
dis = scipy.spatial.distance.euclidean(y[row1], y[row2])

请帮助我改进我的解决方案。

【问题讨论】:

  • 计算所有向量对的距离将比加载文件花费更长的时间。重新检查您是否真的需要所有向量对。此外,您将需要至少 25 * 10^7 * 4 = 10^9 字节,也许 2*10^9 字节——后者在 32 位系统上是不可行的。

标签: python memory numpy scipy


【解决方案1】:

根据您的操作系统和 Python 版本,您很可能永远无法分配 1GB 数组(mgilson 的答案就在此处)。问题不在于您的内存不足,而是您的连续内存不足。如果您使用的是 32 位计算机(尤其是运行 Windows),那么添加更多内存将无济于事。迁移到 64 位架构可能会有所帮助。

使用较小的数据类型肯定会有所帮助;根据您使用的操作,16 位浮点数甚至 8 位整数可能就足够了。

如果这些都不起作用,那么您将不得不承认数据不适合内存。您必须分段处理它(在这种情况下,将数据存储为 HDF5 数组可能非常有用)。

【讨论】:

    【解决方案2】:

    您实际上使用的是 8 字节浮点数,因为 python 的 float 对应于 C 的 double(至少在大多数系统上):

    a=np.arange(10,dtype=float)
    print(a.dtype)  #np.float64
    

    您应该将数据类型指定为np.float32。根据您的操作系统,以及它是 32 位还是 64 位(以及您使用的是 32 位 python 还是 64 位 python),可供 numpy 使用的地址空间可能小于您的 4Gb,这也可能是一个问题.

    【讨论】:

    • 即使我使用dtype=np.float32,也会出现内存错误。
    • @Mahin 如果你这样做会发生什么:>>> a=np.zeros((50000,5000),dtype=np.float32); a=1 而不是你的np.genfromtxt
    • @Mahin -- 我的 numpy 太旧了,无法支持 genfromtxt,但是查看源代码 loadtxt(如果没有缺失值,这应该是等效的),但是,numpy 是将值读入列表(至少为4*N*sizeof(pointer)*N 字节长)。然后(我认为)在构造 numpy 数组时再次复制数据,因为 ndarrays 在内存中是连续的。我建议您自己遍历文件并打包值(在使用 np.zeros 分配内存之后)。由于您知道数组的大小,因此应该相对容易做到。
    猜你喜欢
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 2011-09-27
    • 2011-04-08
    • 2015-02-06
    相关资源
    最近更新 更多