这个特定问题源于尝试处理由 MATLAB 算法生成的大型数据集,以便我可以使用 python 算法处理它们。
背景:我在 MATLAB 中有大型数组(通常为 20x20x40x15000 [i,j,k,frame]),我想在 python 中使用它们。所以我将数组保存到一个 *.mat 文件中,并用于scipy.io.loadmat(fname)将 *.mat 文件读入一个 numpy 数组。但是,出现了一个问题,如果我尝试在 python 中加载整个 *.mat 文件,则会发生内存错误。为了解决这个问题,我将 *.mat 文件切成小块,这样我就可以一次将一个小块加载到 python 数组中。如果我按帧划分 *.mat,我现在有 15,000 个 *.mat 文件,这些文件很快就会变得很麻烦(至少在 Windows 中)。所以我的解决方案是使用压缩文件。
问题:我可以使用 scipy 直接从压缩文件中读取 *.mat 文件,而无需先将文件解压缩到当前工作目录吗?
规格: Python 2.7,Windows XP
当前代码:
import scipy.io
import zipfile
import numpy as np
def readZip(zfilename,dim,frames):
data=np.zeros((dim[0],dim[1],dim[2],frames),dtype=np.float32)
zfile = zipfile.ZipFile( zfilename, "r" )
i=0
for info in zfile.infolist():
fname = info.filename
zfile.extract(fname)
mat=scipy.io.loadmat(fname)
data[:,:,:,i]=mat['export']
mat.clear()
i=i+1
return data
Run Code Online (Sandbox Code Playgroud)
试过的代码:
mat=scipy.io.loadmat(zfile.read(fname))
Run Code Online (Sandbox Code Playgroud)
产生这个错误:
TypeError: file() argument 1 must be encoded string without NULL bytes, not str
Run Code Online (Sandbox Code Playgroud)
mat=scipy.io.loadmat(zfile.open(fname))
Run Code Online (Sandbox Code Playgroud)
产生这个错误:
fileobj.seek(0)
UnsupportedOperation: seek
Run Code Online (Sandbox Code Playgroud)
对处理数据的任何其他建议表示赞赏。
谢谢!
我很确定我的问题的答案是否定的,并且有更好的方法来完成我想做的事情。
无论如何,根据 JF Sebastian 的建议,我设计了一个解决方案。
解决方案:将MATLAB中的数据以HDF5格式保存,即hdf5write(fname, '/data', data_variable). 这会生成一个 *.h5 文件,然后可以通过h5py将其读入 python 中。
蟒蛇代码:
import h5py
r = h5py.File(fname, 'r+')
data = r['data']
Run Code Online (Sandbox Code Playgroud)
我现在可以直接索引数据,但数据仍保留在硬盘上。
print data[:,:,:,1]
Run Code Online (Sandbox Code Playgroud)
或者我可以将其加载到内存中。
data_mem = data[:]
Run Code Online (Sandbox Code Playgroud)
然而,这再次给出了内存错误。因此,为了将其放入内存中,我可以循环遍历每个帧并将其添加到 numpy 数组中。
h5py FTW!