[英]Fitting a 3D array of data to a 1D function with numpy or scipy
4我目前正在尝试将大量数据用于正弦函数。 在我只有一组数据(1D数组)的情况下, scipy.optimize.curve_fit()
工作正常。 然而,如果函数本身只是我所能看到的一维,它不允许更高维数据输入。 我不想使用for循环迭代数组,因为它在python中工作得非常慢。
到目前为止我的代码看起来应该类似于:
from scipy import optimize
import numpy as np
def f(x,p1,p2,p3,p4): return p1 + p2*np.sin(2*np.pi*p3*x + p4) #fit function
def fit(data,guess):
n = data.shape[0]
leng = np.arange(n)
param, pcov = optimize.curve_fit(f,leng,data,guess)
return param, pcov
其中数据是三维数组( shape=(x,y,z)
),我想将每个行data[:,a,b]
拟合到函数,其中param
是(4,y,z)
形状的数组输出。 当然,对于多维数据,这导致a
ValueError: operands could not be broadcast together with shapes (2100,2100) (5)
也许有一个简单的解决方案,但我不知道该怎么做。 有什么建议?
搜索我的问题的答案证明非常困难,因为这些关键字的大多数主题与更高维度函数的拟合有关。
使用np.apply_along_axis()
可以解决您的问题。 这样做:
func1d = lambda y, *args: optimize.curve_fit(f, xdata=x, ydata=y, *args)[0] #<-- [0] to get only popt
param = np.apply_along_axis( func1d, axis=2, arr=data )
请参阅以下示例:
from scipy import optimize
import numpy as np
def f(x,p1,p2,p3,p4):
return p1 + p2*np.sin(2*np.pi*p3*x + p4)
sx = 50 # size x
sy = 200 # size y
sz = 100 # size z
# creating the reference parameters
tmp = np.empty((4,sy,sz))
tmp[0,:,:] = (1.2-0.8) * np.random.random_sample((sy,sz)) + 0.8
tmp[1,:,:] = (1.2-0.8) * np.random.random_sample((sy,sz)) + 0.8
tmp[2,:,:] = np.ones((sy,sz))
tmp[3,:,:] = np.ones((sy,sz))*np.pi/4
param_ref = np.empty((4,sy,sz,sx)) # param_ref in this shape will allow an
for i in range(sx): # one-shot evaluation of f() to create
param_ref[:,:,:,i] = tmp # the data sample
# creating the data sample
x = np.linspace(0,2*np.pi)
factor = (1.1-0.9)*np.random.random_sample((sy,sz,sx))+0.9
data = f(x, *param_ref) * factor # the one-shot evalution is here
# finding the adjusted parameters
func1d = lambda y, *args: optimize.curve_fit(f, xdata=x, ydata=y, *args)[0] #<-- [0] to get only popt
param = np.apply_along_axis( func1d, axis=2, arr=data )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.