Python 为什么这个numpy数组太大而无法加载?
我有一个3.374Gb的npz文件,Python 为什么这个numpy数组太大而无法加载?,python,numpy,file-io,Python,Numpy,File Io,我有一个3.374Gb的npz文件,myfile.npz 我可以在中阅读并查看文件名: a = np.load('myfile.npz') a.files 给予 我能读懂“arr_1”行吗 a1=a['arr_1'] 但是,我无法加载arr_0,也无法读取其形状: a1=a['arr_0'] a['arr_0'].shape 上述两种操作都会导致以下错误: ValueError: array is too big 我有16Gb的RAM,其中8.370Gb可用。所以问题似乎与记忆无关。我的
myfile.npz
我可以在中阅读并查看文件名:
a = np.load('myfile.npz')
a.files
给予
我能读懂“arr_1”行吗
a1=a['arr_1']
但是,我无法加载arr_0
,也无法读取其形状:
a1=a['arr_0']
a['arr_0'].shape
上述两种操作都会导致以下错误:
ValueError: array is too big
我有16Gb的RAM,其中8.370Gb可用。所以问题似乎与记忆无关。我的问题是:
np.memmap
来解决这个问题——这是一个合理的方法吗我访问了一台内存更大(48GB)的计算机并加载了它。
dtype
实际上是complex128
,a['arr_0']
的未压缩内存为5750784000字节。似乎可能需要RAM开销。要么是这一点,要么是我预测的可用RAM量是错误的(我使用的是WindowsSysInternalsRammap) 一个np.complex128
数组的维数(2001440,3,13,32)
应该占用大约5.35GiB的未压缩空间,因此如果您确实有8.3GB的可用可寻址内存,那么原则上您应该能够加载该数组
但是,根据您在下面评论中的回答,您使用的是32位版本的Python和numpy。在Windows中(如果二进制文件是使用IMAGE\u FILE\u LARGE\u ADDRESS\u AWARE
标志编译的,则为4GB;大多数32位Python发行版不是这样)。因此,无论有多少物理内存,Python进程的地址空间都被限制为2GB
您可以安装64位版本的Python、numpy和您需要的任何其他Python库,或者在2GB限制下生活并尝试解决它。在后一种情况下,您可以将超过2GB限制的阵列主要存储在磁盘上(例如,使用np.memmap
),但我建议您选择选项1,因为在大多数情况下,memmaped阵列上的操作要比完全驻留在RAM中的正常np.array
慢得多
如果您已经有了另一台具有足够RAM的机器,可以将整个阵列加载到核心内存中,那么我建议您以不同的格式保存阵列(可以是普通二进制,或者更好,使用or将其保存在HDF5文件中)。也可以从
.npz
文件中提取问题数组,而不将其加载到RAM中,这样您就可以将其作为驻留在磁盘上的np.memmap
数组打开:
import numpy as np
# some random sparse (compressible) data
x = np.random.RandomState(0).binomial(1, 0.25, (1000, 1000))
# save it as a compressed .npz file
np.savez_compressed('x_compressed.npz', x=x)
# now load it as a numpy.lib.npyio.NpzFile object
obj = np.load('x_compressed.npz')
# contains a list of the stored arrays in the format '<name>.npy'
namelist = obj.zip.namelist()
# extract 'x.npy' into the current directory
obj.zip.extract(namelist[0])
# now we can open the array as a memmap
x_memmap = np.load(namelist[0], mmap_mode='r+')
# check that x and x_memmap are identical
assert np.all(x == x_memmap[:])
将numpy导入为np
#一些随机稀疏(可压缩)数据
x=np.随机.随机状态(0).二项式(1,0.25,(1000,1000))
#将其另存为压缩的.npz文件
np.savez_compressed('x_compressed.npz',x=x)
#现在将其作为numpy.lib.npyio.NpzFile对象加载
obj=np.load('x_compressed.npz')
#包含格式为“.npy”的存储数组列表
namelist=obj.zip.namelist()
#将“x.npy”解压缩到当前目录中
obj.zip.extract(名称列表[0])
#现在我们可以将数组作为memmap打开
x_memmap=np.load(名称列表[0],mmap_mode='r+'))
#检查x和x_memmap是否相同
断言np.all(x==x_memmap[:])
我怀疑您无法加载它的原因是,例如,将3.4表示为计算机内存中的浮点值比将3.4保存在磁盘上需要更多的内存。但我比我开始阅读之前更不确定。你知道这个文件是不是被压缩的(是用什么方法创建的)?您是否在尝试加载它的同一台机器上创建了它?你知道它包含什么类型的数组(大小和数据类型)?@ali_m,是与np一起保存的。savez_compressed
但是在另一台机器上。arru0
是浮动(我认为是8字节)的(2001440,3,12,32)
,arru1
是(200,3,32)再次浮动。尝试mmap\u mode='r'
作为np.load
的附加参数。这不应将阵列加载到内存中,而应将其保留在磁盘上。除非您随后将其复制到另一个数组。@Wicket对于包含多个数组的.npz
文件无效(至少在我的计算机上)。当您实际尝试使用a['x']
访问其中一个数组时,整个内容将作为标准np.array
而不是np.memmap
读取到内存中,无论您是否指定mmap\u模式=
。我怀疑数组可能需要连续的虚拟内存空间,至少在某些方面是这样。我也可能是因为他使用的x32进程的地址空间限制为4GB。@atomh33ls您能确认您是在运行32位Windows,还是在其他方面限制为4GB的地址空间吗?您是否能够分配一个新的4GB numpy阵列(例如foo=np.ones(536870912,np.float64)
)?@atomh33ls-Whelp,这是您的问题!要么安装64位版本的Python、numpy和任何其他需要的Python库,要么在可寻址内存的4GB限制下生活。谢谢@ali_m,我天真地认为操作系统只允许使用所有可用的RAM。另外,对于将来阅读的人来说,我发现它是有用的
import numpy as np
# some random sparse (compressible) data
x = np.random.RandomState(0).binomial(1, 0.25, (1000, 1000))
# save it as a compressed .npz file
np.savez_compressed('x_compressed.npz', x=x)
# now load it as a numpy.lib.npyio.NpzFile object
obj = np.load('x_compressed.npz')
# contains a list of the stored arrays in the format '<name>.npy'
namelist = obj.zip.namelist()
# extract 'x.npy' into the current directory
obj.zip.extract(namelist[0])
# now we can open the array as a memmap
x_memmap = np.load(namelist[0], mmap_mode='r+')
# check that x and x_memmap are identical
assert np.all(x == x_memmap[:])