求导数曲线半峰全宽(FWHM)时遇TypeError类型错误求助
解决导数曲线FWHM计算中的TypeError错误
错误根源
你的代码存在以下几个核心问题,导致了TypeError: unsupported operand type(s) for 'list' and 'Float':
fwhm函数中未明确使用numpy的np.amax,且输入的distance、var1是Python原生列表,而scipy.interpolate.splrep/sproot需要numpy数组作为输入- 计算
var1时使用了sympy的exp函数,生成的是sympy符号对象而非数值类型,引发列表与符号Float的运算冲突 curve_fit的maxfev=100过小,可能导致拟合不收敛,你手动写死的参数值准确性无法保证
修正后的完整代码
import numpy as np from scipy.optimize import curve_fit from scipy.interpolate import splrep, sproot import matplotlib.pyplot as plt import sympy as sp def cauchy(x, l, k, x1): return l / (1 + np.exp(-k * (x - x1))) def fwhm(x, y, k=10): # 强制转为numpy数组,确保类型兼容 x = np.array(x) y = np.array(y) half_max = np.amax(y) / 2 s = splrep(x, y - half_max, k=k) roots = sproot(s) return abs(roots[1] - roots[0]) # 数据转numpy数组,避免列表与数组的运算问题 distance = np.array([1000*0.001, 2000*0.001, 3000*0.001, 4000*0.001,5000*0.001,6000*0.001,7000*0.001,8000*0.001, 9000*0.001, 11000*0.001, 12000*0.001, 13000*0.001, 14000*0.001, 15000*0.001, 16000*0.001, 17000*0.001, 18000*0.001, 19000*0.001, 21000*0.001, 22000*0.001, 23000*0.001, 24000*0.001, 25000*0.001, 26000*0.001, 27000*0.001, 28000*0.001, 29000*0.001, 30000*0.001, 31000*0.001, 32000*0.001, 33000*0.001, 34000*0.001, 35000*0.001]) amplitude= np.array([26, 31, 29, 26, 27, 24, 24, 28, 24, 24, 28, 31, 24, 26, 55, 30, 73, 101, 168, 219, 448, 833, 1280, 1397, 1181, 1311, 1715, 1975, 2003, 2034, 2178, 2180, 2182]) plt.plot(distance,amplitude, 'o') # 增大maxfev确保拟合收敛 popt, pcov = curve_fit(cauchy, distance, amplitude, maxfev=10000, bounds=((-10, -10, -10), (3000, 3000, 3000)), p0=[2500, 1, 30]) plt.plot(distance, cauchy(distance, *popt), 'r', label='cauchy fit') # 用sympy求导后转为numpy可调用的数值函数 l_sym, k_sym, x_sym, x1_sym = sp.symbols('l k x x1') expr_diff1 = sp.Derivative(l_sym / (1 + sp.exp(-k_sym*(x_sym - x1_sym))), x_sym).doit() print("Derivative of the function : {}".format(expr_diff1)) # 将符号表达式转为数值函数,避免类型冲突 deriv_func = sp.lambdify((x_sym, l_sym, k_sym, x1_sym), expr_diff1, modules='numpy') # 用拟合得到的参数计算导数曲线,无需手动写死参数 var1 = deriv_func(distance, *popt) * 10 print(var1) plt.plot(distance, var1) # 计算并打印FWHM值 fwhm_value = fwhm(distance, var1) print("FWHM of derivative curve:", fwhm_value) plt.legend() plt.show()
关键修正说明
- 统一数据类型:将所有输入数据转为numpy数组,避免列表与数值对象的运算冲突
- 符号函数转数值函数:用
sp.lambdify将sympy的导数表达式转为numpy兼容的数值函数,彻底解决sympy符号对象的类型问题 - 优化拟合参数:增大
maxfev确保拟合收敛,使用拟合得到的popt参数计算导数,避免手动写死参数的误差 - 明确函数调用:使用
np.amax替代未限定的amax,避免函数引用歧义
内容的提问来源于stack exchange,提问作者Ben Jack
相关产品推荐
相关产品推荐

