Fitting a 3D array of data to a 1D function with numpy or scipy

前端 未结 1 872
小鲜肉
小鲜肉 2020-12-18 09:22

4I am currently trying to fit a lot of data to a sine function. In the case where I only have one set of data (1D array), scipy.optimize.curve_fit() works fine.

相关标签:
1条回答
  • 2020-12-18 09:25

    Using np.apply_along_axis() solves your problem. Just do this:

    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 )
    

    See the example below:

    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 )
    
    0 讨论(0)
提交回复
热议问题