Python Scipy曲线适合二维不工作-对象太深?
我有一个2400 x 2400的数据数组,看起来像这样:Python Scipy曲线适合二维不工作-对象太深?,python,optimization,scipy,curve-fitting,gaussian,Python,Optimization,Scipy,Curve Fitting,Gaussian,我有一个2400 x 2400的数据数组,看起来像这样: data = [[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01... [-2.302670298082603040e-01 -2.304885241061924717e-01
data = [[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
...
我试图拟合以下2D高斯函数:
def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G
def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G.ravel()
对于该数据,使用scipy曲线拟合。因此,我将自变量(坐标)的范围定义如下:
vert = np.arange(2400, dtype=float)
horiz = np.arange(2400, dtype=float)
HORIZ, VERT = np.meshgrid(horiz, vert)
作为参数的初始估计:
po = np.asarray([1200., 1200., 300., 300., 0.14, 0.22, 0.], dtype=float)
以便我可以执行以下拟合:
popt, pcov = curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)
这将返回以下错误消息,我完全不知道原因:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: object too deep for desired array
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-11-ebba75332bfa> in <module>()
----> 1 curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)
/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)
/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
385 maxfev = 200*(n + 1)
386 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 387 gtol, maxfev, epsfcn, factor, diag)
388 else:
389 if col_deriv:
error: Result from function call is not a proper array of floats.
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
ValueError:对象对于所需数组太深
---------------------------------------------------------------------------
错误回溯(最近一次呼叫上次)
在()
---->1曲线拟合(高斯2D,(水平,垂直),数据,p0=po)
/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py曲线拟合(f、扩展数据、ydata、p0、sigma、绝对sigma、检查有限、边界、方法、jac、**kwargs)
734#从kwargs中删除完整输出,否则我们将传入两次。
735 return\u full=kwargs.pop('full\u output',False)
-->736 res=leastsq(func,p0,Dfun=jac,全输出=1,**kwargs)
737 popt、pcov、infodict、ERRMG、ier=res
738成本=总成本(infodict['fvec']**2)
/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py在leastsq中(func、x0、args、Dfun、full_输出、col_deriv、ftol、xtol、gtol、maxfev、epsfcn、factor、diag)
385 maxfev=200*(n+1)
386 retval=\u minpack.\u lmdif(函数、x0、参数、全输出、ftol、xtol、,
-->387 gtol,最大FEV,epsfcn,系数,诊断)
388其他:
389如果col_deriv:
错误:函数调用的结果不是正确的浮点数组。
我不理解消息“对象对于所需数组来说太深”。我还看到了此错误消息的多个在线解决方案,其中一个解决方案是通过确保传递给curve_fit的所有数据类型都是浮点,或者通过检查数组的维度是否正确来修复它。这两种方法我都试过,一次又一次,但都没什么区别。那么这个有什么问题吗?根据评论,这里是一个使用曲线拟合()的3D曲面拟合工具,它有3D散点图、3D曲面图和等高线图
import numpy, scipy, scipy.optimize
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm # to colormap 3D surfaces from blue to red
import matplotlib.pyplot as plt
graphWidth = 800 # units are pixels
graphHeight = 600 # units are pixels
# 3D contour plot lines
numberOfContourLines = 16
def SurfacePlot(func, data, fittedParameters):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
matplotlib.pyplot.grid(True)
axes = Axes3D(f)
x_data = data[0]
y_data = data[1]
z_data = data[2]
xModel = numpy.linspace(min(x_data), max(x_data), 20)
yModel = numpy.linspace(min(y_data), max(y_data), 20)
X, Y = numpy.meshgrid(xModel, yModel)
Z = func(numpy.array([X, Y]), *fittedParameters)
axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)
axes.scatter(x_data, y_data, z_data) # show data along with plotted surface
axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
axes.set_xlabel('X Data') # X axis data label
axes.set_ylabel('Y Data') # Y axis data label
axes.set_zlabel('Z Data') # Z axis data label
plt.show()
plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems
def ContourPlot(func, data, fittedParameters):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
axes = f.add_subplot(111)
x_data = data[0]
y_data = data[1]
z_data = data[2]
xModel = numpy.linspace(min(x_data), max(x_data), 20)
yModel = numpy.linspace(min(y_data), max(y_data), 20)
X, Y = numpy.meshgrid(xModel, yModel)
Z = func(numpy.array([X, Y]), *fittedParameters)
axes.plot(x_data, y_data, 'o')
axes.set_title('Contour Plot') # add a title for contour plot
axes.set_xlabel('X Data') # X axis data label
axes.set_ylabel('Y Data') # Y axis data label
CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours
plt.show()
plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems
def ScatterPlot(data):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
matplotlib.pyplot.grid(True)
axes = Axes3D(f)
x_data = data[0]
y_data = data[1]
z_data = data[2]
axes.scatter(x_data, y_data, z_data)
axes.set_title('Scatter Plot (click-drag with mouse)')
axes.set_xlabel('X Data')
axes.set_ylabel('Y Data')
axes.set_zlabel('Z Data')
plt.show()
plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems
def func(data, a, alpha, beta):
t = data[0]
p_p = data[1]
return a * (t**alpha) * (p_p**beta)
if __name__ == "__main__":
xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])
data = [xData, yData, zData]
initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example
# here a non-linear surface fit is made with scipy's curve_fit()
fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters)
ScatterPlot(data)
SurfacePlot(func, data, fittedParameters)
ContourPlot(func, data, fittedParameters)
print('fitted prameters', fittedParameters)
modelPredictions = func(data, *fittedParameters)
absError = modelPredictions - zData
SE = numpy.square(absError) # squared errors
MSE = numpy.mean(SE) # mean squared errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData))
print('RMSE:', RMSE)
print('R-squared:', Rsquared)
好了,伙计们,我自己解决了这个问题。正如我所怀疑的,这是一个维度问题 应用于二维阵列的曲线拟合的适当尺寸如下所示:
vert = np.arange(2400, dtype=float)
horiz = np.arange(2400, dtype=float)
HORIZ, VERT = np.meshgrid(horiz, vert)
- 函数一个维度,在本例中,除非强制执行,否则该维度与数据集的维度相同
- x数据-(2,n*m),其中n和m是数据数组的维度
- y数据-(n*m)
- 初始参数列表-一个1D数组,仅包含与函数中所述顺序相同的所有参数
def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G
def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G.ravel()
我将以下内容传递给x数据参数:
x = np.vstack((HORIZ.ravel(), VERT.ravel()))
y = data.ravel()
这与y数据参数有关:
x = np.vstack((HORIZ.ravel(), VERT.ravel()))
y = data.ravel()
因此,我使用以下方法对其进行了优化:
curve_fit(Gauss2D, x, y, po)
这很好。只是想弄清楚,什么是
data.shape
和data.dtype
?您需要显示一些数据检查。形状是(24002400),数据类型是float64HORIZ
是一个二维数组(24002400)。你试过用(horiz,vert)
来调用它吗?如果你给我们一个,我们可以复制粘贴并运行的东西,我们可能会提供更多帮助。