为什么我会收到 numpy 内存映射的 OverflowError 和 WindowsError 以及如何解决它?

Why am I getting an OverflowError and WindowsError with numpy memmap and how to solve it?

关于我的另一个问题 ,如果我将一小块数据集与 dtype='int32' 一起使用,则此代码有效,使用 float64 会产生 由于 safe 规则,这部分之后我的主进程出现 TypeError,所以我将坚持使用 int32,但尽管如此,我很好奇并想知道我的错误我越来越。

fp = np.memmap("E:/TDM-memmap.txt", dtype='int32', mode='w+', shape=(len(documents), len(vocabulary)))
matrix = np.genfromtxt("Results/TDM-short.csv", dtype='int32', delimiter=',', skip_header=1)
fp[:] = matrix[:]

如果我使用完整数据(其中 shape=(329568, 27519)),这些 dtypes:

当我使用 int32int

时出现 OverflowError

当我使用 float64

时出现 WindowsError

为什么以及如何解决这个问题?

Edit: Added Tracebacks

int32

的回溯
Traceback (most recent call last):
File "C:/Users/zeferinix/PycharmProjects/Projects/NLP Scripts/NEW/LDA_Experimental1.py", line 123, in <module>
    fp = np.memmap("E:/TDM-memmap.txt", dtype='int32', mode='w+', shape=(len(documents), len(vocabulary)))
File "C:\Python27\lib\site-packages\numpy\core\memmap.py", line 260, in __new__
    mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
WindowsError: [Error 8] Not enough storage is available to process this command

float64

的回溯
Traceback (most recent call last):
File "C:/Users/zeferinix/PycharmProjects/Projects/NLP Scripts/NEW/LDA_Experimental1.py", line 123, in <module>
    fp = np.memmap("E:/TDM-memmap.txt", dtype='float64', mode='w+', shape=(len(documents), len(vocabulary)))
File "C:\Python27\lib\site-packages\numpy\core\memmap.py", line 260, in __new__
    mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
OverflowError: cannot fit 'long' into an index-sized integer

Edit: Added other info

其他可能有帮助的信息: 我有一个 1TB(931 GB 可用)HDD,有 2 个分区,Drive D22.8GB 免费 150GB)我的工作文件包括这个脚本和 memmap 将被写入的位置以及我的 torrent 文件所在的 Drive E406GB 免费 781GB)。起初我尝试将 mmap 文件写入 Drive D,它为 int32[=58= 生成了一个 1,903,283kb 文件 ] 和 3,806,566kb 文件 float64。我想也许是因为它是 space 之外的 运行 这就是为什么我得到这些错误所以我尝试了 Drive E 这应该绰绰有余但是它生成了相同的文件大小并给出相同的错误。

我认为使用 32 位构建的 numpy 不可能生成这么大的 np.memmap 文件,无论您有多少磁盘 space。

np.memmap 试图在内部调用 mmap.mmap 时发生错误。 mmap.mmap 的第二个参数指定文件的字节长度。对于包含 64 位(8 字节)值的 329568 x 27519 数组,长度将为 72555054336 字节(即 ~72GB)。

需要将值72555054336转换为可以作为索引使用的整数类型。在 32 位 Python 中,索引需要是 32 位整数值。但是32位整数所能表示的最大数比72555054336小得多:

print(np.iinfo(np.int32(1)).max)
# 2147483647

即使是 32 位数组也需要 36277527168 字节的长度,这仍然比最大可表示的 32 位整数大 16 倍。

除了切换到 64 位 Python/numpy 之外,我没有看到任何解决此问题的简单方法。这样做还有其他很好的理由 - 32 位 Python 最多只能寻址 3GB 内存,即使您的机器有 8GB 可用内存。


即使你能生成这么大的np.memmap,下一行

matrix = np.genfromtxt("Results/TDM-short.csv", dtype='int32', delimiter=',', skip_header=1)

肯定会失败,因为它需要在 RAM 中创建一个大小为 32GB 的数组。您可以读取该 CSV 文件的唯一方法是将其分成更小的块,就像我在上面的评论中链接到的答案 here 中一样。

正如我在您的其他问题的评论中提到的,您应该做的是将您的 TermDocumentMatrix 转换为 scipy.sparse 矩阵,而不是将其写入 CSV 文件。这将需要更少的存储空间 space 和 RAM,因为它可以利用几乎所有字数都是 zero-valued.

的事实