【问题标题】:TypeError: Improper input: N=3 must not exceed M=1, not sure what's wrong with my dimensions?TypeError:输入不正确:N=3 不得超过 M=1,不确定我的尺寸有什么问题?
【发布时间】:2021-01-05 20:13:25
【问题描述】:

我正在尝试将洛伦兹拟合到我的数据集中的一个峰。

我们得到了高斯拟合,除了实际拟合方程之外,代码非常相似,所以我不确定我哪里出错了。当我使用curve_fit 时,我不明白为什么尺寸会出现问题。

这是我的代码的相关部分,以便更好地了解我在说什么。

读取 CSV 文件并对其进行修整

import csv
import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit
from matplotlib.ticker import StrMethodFormatter

#reading in the csv file 

with open("Data-Oscilloscope.csv") as csv_file: 

    csv_reader = csv.reader(csv_file, delimiter=",")
    time =[]
    voltage_raw = [] 

    for row in csv_reader:
        time.append(float(row[3]))
        voltage_raw.append(float(row[4]))
        print("voltage:", row[4])

#trimming the data 

trim_lower_index = 980
trim_upper_index = 1170

time_trim = time[trim_lower_index:trim_upper_index]
voltage_trim = voltage_raw[trim_lower_index:trim_upper_index]

给定的高斯拟合

#fitting the gaussian function 

def gauss_function(x, a, x0, sigma):
    return a*np.exp(-(x-x0)**2/(2*sigma**2))


popt, pcov = curve_fit(gauss_function, time_trim, voltage_trim, p0=[1,.4,0.1])
perr = np.sqrt(np.diag(pcov))

#plot of the gaussian fit 

plt.figure(2)
plt.plot(time_trim, gauss_function(time_trim, *popt), label = "fit")
plt.plot(time_trim, voltage_trim, "-b")
plt.show()

我尝试的洛伦兹拟合

#x is just the x values, a is the amplitude, x0 is the central value, and f is the full width at half max

def lorentz_function(x, a, x0,f):
    w = f/2 #half width at half max
    return a*w/ [(x-x0)**2+w**2]

popt, pcov = curve_fit(lorentz_function, time_trim, voltage_trim, p0=[1,.4,0.1])

运行此程序时出现错误提示:

in leastsq raise TypeError('不正确的输入:N=%s不能超过M=%s' % (n, m)) TypeError: 输入不当:N=3 不得超过 M=1

我可能遗漏了一些非常明显但看不到的东西。

提前致谢! 编辑:我查看了其他类似的问题并进行了解释,但看不到这些问题如何与我的代码相匹配,因为我的输入的参数数量和维度应该没问题,因为它们适用于高斯拟合。

【问题讨论】:

  • return a*w/ [(x-x0)**2+w**2] 中,您希望方括号能做什么?
  • 啊,谢谢!我没有注意到我是以这种方式输入等式的。有道理为什么它现在不工作了哈哈! Tysm :)
  • 另外,您是否确认time_trimvoltage_trim 包含您期望的数据?错误消息似乎抱怨您试图拟合三个参数,但只有一个数据点。
  • 是的,我已经验证过了。从我的等式中删除方括号解决了这个问题!
  • 现在我想知道为什么最终会以这种奇怪的方式报告错误。相反,我希望它会在lorentz_function 中告诉您有关TypeError 的信息。无论如何,很高兴我能提供帮助。

标签: python numpy curve-fitting scipy-optimize


【解决方案1】:

您没有显示完整的回溯/错误,所以我只能猜测它发生在哪里。它可能正在查看lorentz_function 返回的结果,并发现尺寸错误。因此,虽然错误是由您的函数产生的,但测试是在它的调用者中进行的(在这种情况下是一两级)。

def optimize.curve_fit(
    f,
    xdata,
    ydata,
    p0=None,...    # p0=[1,.4,0.1]
    ...  
    res = leastsq(func, p0, 
    ...

curve_fit 将任务传递给leastsq,其开头为:

def optimize.leastsq(
    func,
    x0,
    args=(), ...

    x0 = asarray(x0).flatten()
    n = len(x0)
    if not isinstance(args, tuple):
        args = (args,)
    shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
    m = shape[0]

    if n > m:
        raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m))

我猜_check_func

 res = func(x0, *args)     # call your func with initial values

并返回res 的形状。该错误表示基于x0 形状的预期结果与func 的结果不匹配。

我猜想使用 3 元素 p0,它抱怨您的函数返回了 1 元素结果(由于 [])。

lorentz 是你的函数。您不测试输出形状,因此它不会引发此错误。

【讨论】:

    【解决方案2】:

    我在产生此错误消息时遇到了类似的问题。 在这种情况下,传递给 optimize.leastsq 的数据数组是矩阵形式。数据似乎必须是 1 行数组。

    例如,调用leastsq的句子是

    result = optimize.leastsq(fit_func, param0, args=(xdata, ydata, zdata))
    

    xdataydatazdata 是 [1 x num] 矩阵形式。原来是

    [[200. .... 350.]]
    

    应该是

    [200. .... 350.]
    

    所以,我不得不添加句子进行转换

    xdata = xdata[0, :]
    

    ydatazdata 也是如此。

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-07-17
      • 2021-03-22
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-05
      • 2019-10-11
      • 1970-01-01
      相关资源
      最近更新 更多