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

求导数曲线半峰全宽(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()

关键修正说明

  1. 统一数据类型:将所有输入数据转为numpy数组,避免列表与数值对象的运算冲突
  2. 符号函数转数值函数:用sp.lambdify将sympy的导数表达式转为numpy兼容的数值函数,彻底解决sympy符号对象的类型问题
  3. 优化拟合参数:增大maxfev确保拟合收敛,使用拟合得到的popt参数计算导数,避免手动写死参数的误差
  4. 明确函数调用:使用np.amax替代未限定的amax,避免函数引用歧义

内容的提问来源于stack exchange,提问作者Ben Jack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:51:04