69

出于科学目的,我需要生成大型(非常)矩阵(马尔可夫链)。我执行微积分,并将其放入 20301 个元素的列表(=我的矩阵的一行)。我需要内存中的所有这些数据来进行下一个马尔可夫步骤,但如果需要,我可以将它们存储在其他地方(例如文件),即使它会减慢我的马尔可夫链遍历速度。我的电脑(科学实验室):双氙气6核/12线程,12GB内存,操作系统:win64

  Traceback (most recent call last):
  File "my_file.py", line 247, in <module>
    ListTemp.append(calculus)
MemoryError

微积分结果示例:9.233747520008198e-102(是的,超过 1/9000)

存储第 19766 个元素时引发错误:

ListTemp[19766]
1.4509421012263216e-103

如果我走得更远

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    ListTemp[19767]
IndexError: list index out of range

所以这个列表在 19767 循环中有一个内存错误。

问题:

  1. 列表有内存限制吗?它是“按列表限制”还是“全局每个脚本限制”?

  2. 如何绕过这些限制?有什么可能吗?

  3. 使用 numpy、python64 会有帮助吗?它们的内存限制是多少?其他语言呢?

4

4 回答 4

58

首先,看看 Python 数组能有多大?Numpy,长数组的问题

其次,唯一真正的限制来自您拥有的内存量以及您的系统如何存储内存引用。没有每个列表的限制,因此 Python 会一直运行到内存不足为止。两种可能:

  1. 如果您在较旧的操作系统或强制进程使用有限内存量的操作系统上运行,您可能需要增加 Python 进程可以访问的内存量。
  2. 使用分块将列表分开。例如,执行列表的前 1000 个元素,腌制并将它们保存到磁盘,然后执行接下来的 1000 个。要使用它们,一次取消腌制一个块,以免内存不足。这本质上与数据库用于处理超出 RAM 容量的数据的技术相同。
于 2011-04-04T11:23:57.973 回答
30

您看到的MemoryError异常是可用 RAM 用完的直接结果。这可能是由于 Windows(32 位程序)施加的每个程序限制为 2GB,或者您的计算机上缺少可用 RAM。(此链接指向上一个问题)。

如果您使用的是 Windows 的 64 位副本,您应该能够使用 64 位的 Python 副本来扩展 2GB。

IndexError是因为 PythonMemoryError 在计算整个数组之前遇到了异常。这又是一个内存问题。

为了解决这个问题,您可以尝试使用 Python 的 64 位副本,或者更好地找到将结果写入文件的方法。为此,请查看 numpy 的内存映射数组

您应该能够将整个计算集运行到其中一个数组中,因为实际数据将写入磁盘,并且只有一小部分保存在内存中。

于 2011-04-04T11:22:56.880 回答
8

Python 没有内存限制。MemoryError但是,如果您的 RAM 用完,您会得到一个。你说你有 20301 个元素list。这似乎太小而不会导致简单数据类型(例如int)的内存错误,但是如果每个元素本身都是一个占用大量内存的对象,那么您很可能会耗尽内存。

然而IndexError,这可能是因为您ListTemp只有 19767 个元素(索引 0 到 19766),并且您试图访问最后一个元素。

很难说你可以做些什么来避免达到极限,而不知道你正在尝试做什么。使用numpy可能会有所帮助。看起来您正在存储大量数据。可能您不需要在每个阶段都存储所有这些。但不知道是不可能说出来的。

于 2011-04-04T11:15:25.447 回答
0

如果你想规避这个问题,你也可以使用搁置。然后,您将创建与您的机器处理能力大小相同的文件,并且仅在必要时将它们放在 RAM 上,基本上是写入 HD 并将信息分段拉回,以便您可以处理它。

创建二进制文件并检查信息是否已经在其中,如果是,则创建一个局部变量来保存它,否则写入一些您认为必要的数据。

Data = shelve.open('File01')
   for i in range(0,100):
     Matrix_Shelve = 'Matrix' + str(i)
     if Matrix_Shelve in Data:
        Matrix_local = Data[Matrix_Shelve]
     else:
        Data[Matrix_Selve] = 'somenthingforlater'

希望它听起来不会太古板。

于 2018-03-30T19:21:18.100 回答