Python 如何将一个大“numpy”保存为';*。npz&x27;文件系统容量有限的阵列?

Python 如何将一个大“numpy”保存为';*。npz&x27;文件系统容量有限的阵列?,python,python-3.x,numpy,low-memory,Python,Python 3.x,Numpy,Low Memory,我有一个numpy数组,它保存为一个未压缩的'*npz'文件,与numpy.float32和numpy.savez()一样,大约为26 GiB,结尾为: OSError: Failed to write to /tmp/tmpl9v3xsmf-numpy.npy: 6998400000 requested and 3456146404 written 我想将其压缩保存可以节省时间,但使用numpy.savez_compressed()我还有: OSError: Failed to write

我有一个
numpy
数组,它保存为一个未压缩的'*npz'文件,与
numpy.float32
numpy.savez()一样,大约为26 GiB,结尾为:

OSError: Failed to write to /tmp/tmpl9v3xsmf-numpy.npy: 6998400000 requested and 3456146404 written
我想将其压缩保存可以节省时间,但使用
numpy.savez_compressed()
我还有:

OSError: Failed to write to /tmp/tmp591cum2r-numpy.npy: 6998400000 requested and 3456157668 written
as
numpy.savez_compressed()
首先保存未压缩的数组

显然,“使用附加存储”我不考虑答案。p> [编辑]


标签
内存不足
指的是磁盘内存,而不是RAM。

注意:我非常乐意接受更有效的RAM解决方案。

我已经浏览了
numpy.savez_compressed()
代码,并决定重新实现其部分功能:

import numpy as np
import zipfile
import io

def saveCompressed(fh, **namedict):
     with zipfile.ZipFile(fh,
                          mode="w",
                          compression=zipfile.ZIP_DEFLATED,
                          allowZip64=True) as zf:
         for k, v in namedict.items():
             buf = io.BytesIO()
             np.lib.npyio.format.write_array(buf,
                                             np.asanyarray(v),
                                             allow_pickle=False)
             zf.writestr(k + '.npy',
                         buf.getvalue())
它会导致我的系统交换,但至少我能够存储我的数据(示例中使用的假数据):


注意:我非常乐意接受一个更高效的RAM解决方案。

我已经浏览了
numpy.savez_compressed()
代码,并决定重新实现其部分功能:

import numpy as np
import zipfile
import io

def saveCompressed(fh, **namedict):
     with zipfile.ZipFile(fh,
                          mode="w",
                          compression=zipfile.ZIP_DEFLATED,
                          allowZip64=True) as zf:
         for k, v in namedict.items():
             buf = io.BytesIO()
             np.lib.npyio.format.write_array(buf,
                                             np.asanyarray(v),
                                             allow_pickle=False)
             zf.writestr(k + '.npy',
                         buf.getvalue())
它会导致我的系统交换,但至少我能够存储我的数据(示例中使用的假数据):


通过在Python 3.6中添加
ZipFile.open(…,mode='w')
,您可以做得更好:

import numpy as np
import zipfile
import io

def saveCompressed(fh, **namedict):
     with zipfile.ZipFile(fh, mode="w", compression=zipfile.ZIP_DEFLATED,
                          allowZip64=True) as zf:
         for k, v in namedict.items():
             with zf.open(k + '.npy', 'w', force_zip64=True) as buf:
                 np.lib.npyio.format.write_array(buf,
                                                 np.asanyarray(v),
                                                 allow_pickle=False)

通过在Python 3.6中添加
ZipFile.open(…,mode='w')
,您可以做得更好:

import numpy as np
import zipfile
import io

def saveCompressed(fh, **namedict):
     with zipfile.ZipFile(fh, mode="w", compression=zipfile.ZIP_DEFLATED,
                          allowZip64=True) as zf:
         for k, v in namedict.items():
             with zf.open(k + '.npy', 'w', force_zip64=True) as buf:
                 np.lib.npyio.format.write_array(buf,
                                                 np.asanyarray(v),
                                                 allow_pickle=False)

你在那个数组中保存的是什么样的数据?@Kasramvd floats,特别是
numpy.float32
难道你不能使用一种更轻的格式,比如
float16
int8
uint8
,等等?如果你有一个如此大的数组并且需要这样的精度,那么存储它需要多少钱。唯一可以真正减少它的方法(除了通用压缩)是如果数据中存在已知模式,例如,它是稀疏数组,还是存在重复值或派生值?如果所有的值都有大约相同的指数,那么在
int16
/
uint16
中只存储尾数就足够了?另外,你知道你的文件系统是什么吗?它可能会限制您可以存储的文件的大小。@CharlesDuffy好吧,我想您必须先将其保存到一个BytesIO对象,然后压缩它。由于memroy的需求,这可能也不是解决方案……您在该数组中保存的是什么类型的数据?@Kasramvd floats,特别是
numpy.float32
您不能使用更轻的格式,如
float16
int8
uint8
,等等?如果您有这么大的数组并且需要这样的精度,这就是储存它所需的费用。唯一可以真正减少它的方法(除了通用压缩)是如果数据中存在已知模式,例如,它是稀疏数组,还是存在重复值或派生值?如果所有的值都有大约相同的指数,那么在
int16
/
uint16
中只存储尾数就足够了?另外,你知道你的文件系统是什么吗?它可能会限制您可以存储的文件的大小。@CharlesDuffy好吧,我想您必须先将其保存到一个BytesIO对象,然后压缩它。由于memroy demand,这可能也不是解决方案……看起来几乎和我现在测试的实现完全一样,除了
使用zf.open(k+'.npy',mode='w',force_zip64=True)作为buf:
使用
zf.open()
是关键区别,因为它允许在zip中创建的文件以增量方式写入(因此,使用sane ZipFile实现,内存使用有限)。我指的是
,force_zip64=True
部分。您的代码以
值结尾。错误:当ZIP文件上有一个打开的写入句柄时,无法关闭它。请在关闭ZIP之前关闭写入句柄。
。我猜它大约是数组的大小。您介意在您的答案中包含
force_zip64=True
部分吗?看起来很简单t与我现在测试的实现完全一样,除了使用zf.open(k+'.npy',mode='w',force_zip64=True)作为buf的
之外:
使用
zf.open()
是关键区别,因为它允许在zip中创建的文件以增量方式写入(因此,使用一个正常的ZipFile实现,内存使用有限)。我指的是
,force_zip64=True
部分。您的代码以
值结尾。错误:当ZIP文件上有一个打开的写入句柄时,无法关闭它。请在关闭ZIP之前关闭写入句柄。
。我猜它与数组的大小有关。您是否介意在回答中包含
force_zip64=True
部分?