【问题标题】:Read matlab file (*.mat) from zipped file without extracting to directory in Python从压缩文件中读取 matlab 文件 (*.mat) 而无需解压到 Python 中的目录
【发布时间】:2012-06-21 18:50:56
【问题描述】:

这个具体问题源于尝试处理由 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

试用过的代码:

mat=scipy.io.loadmat(zfile.read(fname))

产生这个错误:

TypeError: file() argument 1 must be encoded string without NULL bytes, not str

mat=scipy.io.loadmat(zfile.open(fname))

产生这个错误:

fileobj.seek(0)
UnsupportedOperation: seek

对于处理数据的任何其他建议表示赞赏。

谢谢!

【问题讨论】:

  • 您必须预先阅读整个文件吗?你能解压它并即时处理吗?
  • @matcheek,我想我可以,但是,我更喜欢将数组放在内存中,这样我就可以在数组上使用各种算法并使用 vtk 生成动画。
  • 您的代码表明整个数组适合内存,即只有加载过程会导致MemoryError。你在matlab中开启mat-file压缩了吗?
  • @J.F.Sebastian 我没试过,不知道scipy是否支持
  • @Onlyjus:应该(至少消息来源建议)。其他选项: - 提取文件,但加载后立即删除; - 使用 HDF5 格式 (matlab 7.3) 保存并使用 h5pyPyTables 加载

标签: python matlab zip


【解决方案1】:

我很确定我的问题的答案是,并且有更好的方法来完成我想要做的事情。

无论如何,根据 J.F. Sebastian 的建议,我已经设计了一个解决方案。

解决方法: 将MATLAB中的数据保存为HDF5格式,即hdf5write(fname, '/data', data_variable)。这会生成一个 *.h5 文件,然后可以通过 h5py 将其读入 python。

python 代码:

import h5py

r = h5py.File(fname, 'r+')
data = r['data']

我现在可以直接索引数据,但它仍保留在硬盘上。

print data[:,:,:,1]

或者我可以将它加载到内存中。

data_mem = data[:]

但是,这再次导致内存错误。因此,为了将其放入内存,我可以遍历每一帧并将其添加到一个 numpy 数组中。

h5py FTW!

【讨论】:

    【解决方案2】:

    在我的一个冻结应用程序中,我们将一些文件捆绑到 py2exe 创建的 .bin 文件中,然后像这样将它们拉出:

    z = zipfile.ZipFile(os.path.join(myDir, 'common.bin'))
    
    data = z.read('schema-new.sql')
    

    我不确定这是否会将您的 .mat 文件输入 scipy,但我认为值得一试。

    【讨论】:

    • 我厌倦了使用 'data=z.read(fname)' 和 'data=z.open(fname)',但是 'scipy.io.loadmat(data)' 适合,因为 data 是'str'
    猜你喜欢
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2015-12-26
    • 1970-01-01
    • 2022-01-14
    相关资源
    最近更新 更多