【问题标题】:Why does SciPy's loadmat throw a MemoryError when reading a 200 MB Matlab struct为什么 SciPy 的 loadmat 在读取 200 MB Matlab 结构时会抛出 MemoryError
【发布时间】:2012-06-18 23:13:43
【问题描述】:

我正在使用以下代码尝试在 Python 中加载 MAT 文件。我可以在 MATLAB 中毫无问题地加载它。

from scipy.io import loadmat
test_filename = 'test_data.mat' #This is a struct
data =loadmat(test_filename, struct_as_record=True)

运行该代码会产生此错误:

Traceback (most recent call last):
  File "C:\Users\mac389\workspace\nexUtils\src\qA.py", line 16, in <module>
data =loadmat(test_filename, struct_as_record=True)
  File "C:\Python27\lib\site-packages\scipy\io\matlab\mio.py", line 175, in loadmat
matfile_dict = MR.get_variables(variable_names)
  File "C:\Python27\lib\site-packages\scipy\io\matlab\mio5.py", line 272, in get_variables
hdr, next_position = self.read_var_header()
  File "C:\Python27\lib\site-packages\scipy\io\matlab\mio5.py", line 224, in read_var_header
stream = BytesIO(dcor.decompress(data))
MemoryError

作为参考,test_data.mat 是一个包含以下字段的结构体(来自 MATLAB 控制台):

 version: 101
 comment: 'molecular layer 4/17'
    freq: 40000
    tbeg: 0
    tend: 1.3950e+003
  events: {3x1 cell}
 neurons: {50x1 cell}
   waves: {102x1 cell}
contvars: {64x1 cell}

Test_data.mat 为 217 MB。我有 4 GB 的 RAM。我正在使用 SciPy 0.10.0 和 NumPy 1.6.1。更改 'struct_as_record' 字段没有任何作用。

如何加载字段为元胞数组的结构?

【问题讨论】:

  • 您的内存不足。虽然文件可能只有 200MB,但内存需求可能会更大。
  • .mat 文件压缩了吗?你的 Python 进程是 32 位的吗?你的 MATLAB 进程是 64 位的吗?
  • @David:mat 文件在 matlab 的二进制格式之外没有进一步压缩。两个进程都是 32 位的。我的问题是为什么加载一个小文件会占用 Python 中的内存而不是 matlab 以及我可以做些什么来规避它。
  • @David 我认为,根据堆栈跟踪,loadmat 在读取结构字段名称时会卡住。这可能不仅仅是“文件太大的问题”。

标签: python matlab file-io scipy mat-file


【解决方案1】:

我找到了答案。

Loadmat 无法处理大量嵌套的结构。在给定的数据集中,三个结构字段“waves、neurer、contvars”是元胞数组。该单元数组的每个成员都是一个结构。这些结构的一些字段本身就是元胞数组。这些元胞数组有一个包含数据的字段。这种组织数据的非标准方式加上缺乏文档造成了问题。

我想这可以作为一个警示故事,尽可能接近文本文件格式,如果您正在创建数据存储格式,如果您选择一种非常非标准的格式,请怜悯您的继任者并记录这一事实......

【讨论】:

    【解决方案2】:

    我认为由于解压的实现方式,它在 Python 中需要更多的内存。尝试在 Matlab 中不压缩保存(使用-v6,版本 6 格式没有压缩功能)。

    【讨论】:

    • 这将有助于确定问题是否出在内存上。感谢您提供有用的诊断建议。但是,那该怎么办呢?
    • 好吧,您无能为力。如果可行,您可以坚持在 Matlab 端使用 v6(您可以将其设置为默认保存格式)。否则,您将需要在 Python 端升级内存并切换到 64 位。或者你可以看看使用不同的格式。 Matlab 可以写入 HDF5,这在 Python 中得到了很好的支持,所以如果你可以转换你的数据以适应 HDF5 容器,也许这对你有用。
    猜你喜欢
    • 2015-02-25
    • 2011-08-26
    • 1970-01-01
    • 2017-02-13
    • 2019-05-26
    • 2020-10-26
    • 2013-02-04
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多