Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用numpy或scipy将三维数据阵列拟合到一维函数_Python_Arrays_Numpy_Scipy - Fatal编程技术网

Python 使用numpy或scipy将三维数据阵列拟合到一维函数

Python 使用numpy或scipy将三维数据阵列拟合到一维函数,python,arrays,numpy,scipy,Python,Arrays,Numpy,Scipy,4I目前正在尝试将大量数据拟合到正弦函数。在我只有一组数据(1D数组)的情况下,scipy.optimize.curve\u fit()可以正常工作。然而,如果函数本身在我看来只是一维的,它就不允许更高维的数据输入。我不想使用for循环迭代数组,因为在python中它的速度非常慢 到目前为止,我的代码应该与此类似: from scipy import optimize import numpy as np def f(x,p1,p2,p3,p4): return p1 + p2*np.s

4I目前正在尝试将大量数据拟合到正弦函数。在我只有一组数据(1D数组)的情况下,
scipy.optimize.curve\u 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)
形状数组作为输出。 当然,对于多维数据,这会导致

ValueError:操作数无法与形状(21002100)(5)一起广播

也许有一个简单的解决办法,但我不知道如何做到这一点。有什么建议吗

搜索我的问题的答案非常困难,因为大多数带有这些关键字的主题都与高维函数的拟合有关。

使用可以解决您的问题。只要这样做:

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 )

func1d=lambda y,*args:optimize.curve_fit(f,xdata=x,ydata=y,*args)[0]#不要担心循环太小。我很确定曲线拟合无论如何都会是代码中缓慢的一部分。如果怀疑循环是瓶颈,请分析代码!这个想法是,如果曲线拟合可以使用整个数组,而不是运行函数y*z次,那么曲线拟合会快得多。这就是我说for循环很慢的意思。也许你可以通过FFT得到sin的参数。为什么曲线拟合要快得多?大部分时间可能会花在拟合例程上,而不是在数据循环上。我希望它会更快,因为这是我在比较for-loop方法(通过直接将整个数组输入函数)来遍历数据数组时与其他例程的经验(高达因子100)。我承认,这些都是相当简单的计算,也许使用更耗时的方法(如曲线拟合)所节省的时间可能不那么重要,但我仍然希望这一过程能有一点加速。我也尝试过使用FFT,但是由于我拥有的采样点很少,结果不是很令人满意。谢谢你的回答,这确实有效。不幸的是,与使用for循环的方法相比,它并没有加快这个过程。我想David Zwicker关于需要大量计算时间的fit函数是对的。是的,你是对的,显然
apply_沿_轴
vectorize
apply_over_轴
与Python
for
循环相比,没有提供任何性能增益,但它们确实简化了代码。。。
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 )