You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scipy.io.loadmat开启simplify_cells=True时加载含匿名函数的Matlab结构失败

解决Scipy.io.loadmat加载含匿名函数的.mat文件时的IndexError问题

问题概述

使用scipy.io.loadmat并设置simplify_cells=True时,加载包含匿名函数的Matlab结构文件会触发IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed错误。原因是匿名函数被解析为0维mat_struct数组,而开启simplify_cells后,内部处理逻辑要求mat_struct对象至少为1维。

复现步骤

  1. 在Matlab中生成测试文件:
exStruct = struct();             % 创建结构体
exStruct.anonymous = @(x) x;     % 添加匿名函数字段
save('exStruct.mat','exStruct')  % 保存为.mat文件
  1. 在Python中触发错误:
import scipy.io as scio
fileName = 'exStruct.mat'
matStruct = scio.loadmat(fileName, simplify_cells=True) 

问题根源

错误来自scipy.io.matlab._mio5.py中的_has_struct函数(第106行):

def _has_struct(elem):
    """Determine if elem is an array and if first array item is a struct."""
    return (isinstance(elem, np.ndarray) and (elem.size > 0) and
            isinstance(elem[0], mat_struct))

该函数直接尝试对数组执行elem[0]索引操作,但匿名函数被加载为0维mat_struct数组,0维数组不支持这种索引方式,因此抛出错误。

解决方案

方案1:修改Scipy内部函数(临时修复)

修改_has_struct函数,增加数组维度判断,确保仅对1维及以上数组进行索引:

def _has_struct(elem):
    """Determine if elem is an array and if first array item is a struct."""
    return (isinstance(elem, np.ndarray) and (elem.size > 0) and
            elem.ndim > 0 and isinstance(elem[0], mat_struct))

修改后可正常加载文件,但匿名函数字段仍无法在Python中执行。

方案2:不启用simplify_cells,手动处理结构

先关闭simplify_cells加载文件,再手动转换结构:

import scipy.io as scio
import numpy as np

fileName = 'exStruct.mat'
# 不启用simplify_cells加载
matStruct = scio.loadmat(fileName, struct_as_record=False, squeeze_me=True)
exStruct = matStruct['exStruct']

# 手动处理结构体字段
def simplify_struct(s):
    if isinstance(s, np.ndarray) and s.ndim == 0:
        return s.item()
    elif hasattr(s, '_fieldnames'):
        return {f: simplify_struct(getattr(s, f)) for f in s._fieldnames}
    else:
        return s

simplified_exStruct = simplify_struct(exStruct)

此方法可避免报错,同时完成结构简化,但同样无法运行匿名函数。

方案3:使用第三方库加载

如果不需要保留匿名函数,或仅需加载其他字段,可尝试使用mat73库(支持Matlab 7.3及以上版本的文件):

import mat73

data = mat73.loadmat('exStruct.mat')

mat73对复杂结构的兼容性更好,但同样无法解析Matlab匿名函数。

注意事项

无论采用哪种方案,Python都无法直接运行Matlab的匿名函数,因为两者的字节码格式和运行时环境完全不同,匿名函数的逻辑无法在Python中解析执行。

内容的提问来源于stack exchange,提问作者Andrew Landau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:52:42