Python 为什么numpy memmap会出现溢出错误和窗口错误,以及如何解决?

Python 为什么numpy memmap会出现溢出错误和窗口错误,以及如何解决?,python,numpy,numpy-memmap,Python,Numpy,Numpy Memmap,关于我的另一个问题,如果我将数据集的一小部分用于dtype='int32',使用float64会在这部分之后的主进程上产生TypeError,因为safe规则,所以我会坚持使用int32,但是,我很好奇,想知道我所犯的错误 fp = np.memmap("E:/TDM-memmap.txt", dtype='int32', mode='w+', shape=(len(documents), len(vocabulary))) matrix = np.genfromtxt("Results/TDM

关于我的另一个问题,如果我将数据集的一小部分用于
dtype='int32'
,使用
float64
会在这部分之后的主进程上产生TypeError,因为
safe
规则,所以我会坚持使用
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=(32956827519)
)与这些数据类型一起使用:

当我使用int32int

当我使用float64时,我得到了WindowsError

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
为什么以及如何修复此问题

编辑:添加了回溯

对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
回溯(最近一次呼叫最后一次):
文件“C:/Users/zeferinix/PycharmProjects/Projects/NLP Scripts/NEW/LDA_Experimental1.py”,第123行,在
fp=np.memmap(“E:/TDM memmap.txt”,dtype='int32',mode='w+',shape=(len(文档),len(词汇)))
文件“C:\Python27\lib\site packages\numpy\core\memmap.py”,第260行,新__
mm=mmap.mmap(fid.fileno(),字节,access=acc,offset=start)
WindowsError:[错误8]没有足够的存储空间来处理此命令
对浮动64的回溯

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
回溯(最近一次呼叫最后一次):
文件“C:/Users/zeferinix/PycharmProjects/Projects/NLP Scripts/NEW/LDA_Experimental1.py”,第123行,在
fp=np.memmap(“E:/TDM memmap.txt”,dtype='float64',mode='w+',shape=(len(文档),len(词汇)))
文件“C:\Python27\lib\site packages\numpy\core\memmap.py”,第260行,新__
mm=mmap.mmap(fid.fileno(),字节,access=acc,offset=start)
溢出错误:无法将“long”放入索引大小的整数中
编辑:添加其他信息

其他可能有帮助的信息:
我有一个1TB(可用931GB)硬盘,有两个分区,驱动器D22.8GB不含150GB),其中我的工作文件包括这个脚本,memmap将被写入其中,驱动器E406GB不含781GB),我的torrent文件将被放入其中。起初,我试图将mmap文件写入驱动器D,它为int32生成了1903283KB的文件,为float64生成了3806566KB的文件。我想可能是因为空间不够,这就是为什么我会出现这些错误,所以我尝试了驱动器E,这应该足够了,但它生成了相同的文件大小,并给出了相同的错误。

我认为不可能使用32位numpy构建生成如此大的
np.memmap
文件,无论您有多少磁盘空间

np.memmap
尝试在内部调用时会发生错误。
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的RAM,即使您的机器有8GB可用内存


即使您可以生成一个
np.memmap
那么大,下一行

matrix = np.genfromtxt("Results/TDM-short.csv", dtype='int32', delimiter=',', skip_header=1)
肯定会失败,因为它需要在内存中创建一个32GB大小的阵列。您可能阅读该CSV文件的唯一方法是将其分成更小的块,就像我在上面的评论中链接到的答案一样


正如我在您的另一个问题的评论中提到的,您应该做的是将
术语DocumentMatrix
转换为
scipy.sparse
矩阵,而不是将其写入CSV文件。这将需要非常少的存储空间和RAM,因为它可以利用几乎所有的字数都是零值的这一事实。

使用
np.genfromtxt
,您将无法一次性读取该文件-使用int32生成的数组将占用约36GB的RAM,而对于int或float64,将占用两倍的RAM。这里使用内存映射数组的意义在于,它允许您以较小的块读取文件,然后将每个块写入内存映射数组,这样您就不必一次将整个内容保存在内存中。再看看我的答案,看看这是怎么回事。@ali_m为int32和float64添加了回溯,这两个报告都
memmap.py
@ali_m我有一个1TB(931GB可用)硬盘,有两个分区,
驱动器D
(22.8GB不含150GB)`我的工作文件包括这个脚本,memmap将被写入的地方,以及我的torrent文件所在的
驱动器E
(406GB免费781GB)。起初,我试图将mmap文件写入驱动器D,它为int32生成了1903283KB的txt文件,为float64生成了3806566KB的txt文件。我想可能是因为它的空间不足,这就是为什么我会出现这些错误,所以我尝试了
Drive E
,这应该足够了,但它生成了相同的文件大小,并给出了相同的错误。@ali_m done,我使用的是32位版本的numpy。@ali_很抱歉,是的,我指的是由
np.memmap
生成的文件。我在创建文件时添加了一个
.txt
扩展名,所以我把它误认为是一个txt文件,我的坏。我明白了,这是有道理的。感谢您的精确计算和解释!可能会放弃这种方法,因为它效率低下