从Matlab调用Python函数时出现'memoryview'无'iloc'属性错误
问题分析与解决方案
错误原因
- Matlab传递的参数类型问题:Matlab向Python传递的数组默认是
memoryview对象,而非numpy数组,后续代码中对该对象的操作会触发隐式逻辑,导致出现'memoryview' object has no attribute 'iloc'的错误。 - Python代码语法错误:
calc_BiasCorr函数内的for循环未缩进,属于语法错误,会直接中断代码执行。- 多余的
BiasCorr = BiasCorr()语句:该函数需要传入参数,无参调用会报错,且覆盖了原函数定义。
- 变量作用域问题:原代码依赖全局变量
OptParameters,未在函数内声明作用域,可能导致无法正确修改并返回结果。
修正后的Python代码
import numpy as np from scipy.optimize import curve_fit # 定义元素列表 Elts = ['Fe', 'SiO2', 'Al2O3'] # 定义拟合参数的上下界 InitialParameters_Lower = np.array([[-5, -5, 0.1, 50], [-5, -5, 0.1, 0], [-5, 0, 0.1, 0]]) InitialParameters_Upper = np.array([[5, 5, 2, 70], [5, 5, 2, 10], [5, 5, 2, 10]]) # 定义偏差校正函数 def BiasCorr(x, L, k, x0, T): return L / (1 + np.exp(-k * (x - x0))) + T # 拟合结果占位符 fitresult = {} gof = {} def calc_BiasCorr(CompoAssay, CompoAssayFG): # 将Matlab传递的memoryview对象转换为numpy数组 CompoAssay = np.array(CompoAssay) CompoAssayFG = np.array(CompoAssayFG) # 在函数内初始化参数数组,避免全局变量依赖 OptParameters = np.zeros((len(Elts), 4)) for elt_index, elt in enumerate(Elts): # 准备拟合数据 Labelt = CompoAssay[:, elt_index] FGbiaselt = CompoAssayFG[:, elt_index] - CompoAssay[:, elt_index] # 获取当前元素的参数上下界 lower_bounds = InitialParameters_Lower[elt_index] upper_bounds = InitialParameters_Upper[elt_index] # 标记异常值 P = np.percentile(FGbiaselt, [5, 95]) I = (FGbiaselt < P[0]) | (FGbiaselt > P[1]) # 过滤异常值 Labelt_filtered = Labelt[~I] FGbiaselt_filtered = FGbiaselt[~I] # 初始参数猜测与曲线拟合 initial_guess = [0.95, 0.96, 0.15, 0.97] popt, pcov = curve_fit(BiasCorr, Labelt_filtered, FGbiaselt_filtered, p0=initial_guess, bounds=(lower_bounds, upper_bounds)) # 存储拟合结果 fitresult[elt_index] = popt OptParameters[elt_index, :] = popt return OptParameters # 执行计算并赋值给OptP,供Matlab获取结果 OptP = calc_BiasCorr(CompoAssay, CompoAssayFG)
关键修改说明
- 参数类型转换:在函数开头将
memoryview转为numpy数组,确保后续切片、数值计算等操作正常运行。 - 修复语法错误:给
for循环添加缩进,删除无意义的BiasCorr = BiasCorr()调用。 - 优化变量作用域:在函数内初始化参数数组,避免全局变量带来的作用域问题,逻辑更清晰可靠。
Matlab调用说明
保持原调用语句不变即可,执行后OptP会被正确返回到Matlab工作区:
OptP = pyrunfile("test_curve_fit_python.py", "OptP", CompoAssay=CompoAssay(:,3:5), CompoAssayFG=CompoAssayFG(:,1:3))
内容的提问来源于stack exchange,提问作者user1499565
相关产品推荐
相关产品推荐

