Numpy 如何拟合三维数据
我有一个3D点列表,我想将该点拟合到球体:Numpy 如何拟合三维数据,numpy,scipy,Numpy,Scipy,我有一个3D点列表,我想将该点拟合到球体: R^2 = (x-x0)^2 + (y-y0)^2 + (z-z0)^2 所以我想,我应该表示z,并用4个参数(x0、y0、z0和R)拟合2D数据: 下面是一个代码(它是更大项目的一部分): 我得到一个错误: ValueError: operands could not be broadcast together with shapes (2) (1404) 这里是到的链接。您需要正确定义您的fitfunc: fitfunc = lambda p,
R^2 = (x-x0)^2 + (y-y0)^2 + (z-z0)^2
所以我想,我应该表示z,并用4个参数(x0、y0、z0和R)拟合2D数据:
下面是一个代码(它是更大项目的一部分):
我得到一个错误:
ValueError: operands could not be broadcast together with shapes (2) (1404)
这里是到的链接。您需要正确定义您的
fitfunc
:
fitfunc = lambda p, x: sqrt(p[3]**2 - (x[:, 0] - p[0])**2 - (x[:, 1] - p[1])**2) + p[2]
我认为你的方法不是很稳健,因为当你采用sqrt
时,有两种解决方案,一种是积极的,一种是消极的,而你只考虑积极的。因此,除非你的所有点都在球体的上半部分,否则你的方法将不起作用。最好将r
设置为您的fitfunc:
import numpy as np
from scipy.optimize import leastsq
# test data: sphere centered at 'center' of radius 'R'
center = (np.random.rand(3) - 0.5) * 200
R = np.random.rand(1) * 100
coords = np.random.rand(100, 3) - 0.5
coords /= np.sqrt(np.sum(coords**2, axis=1))[:, None]
coords *= R
coords += center
p0 = [0, 0, 0, 1]
def fitfunc(p, coords):
x0, y0, z0, R = p
x, y, z = coords.T
return np.sqrt((x-x0)**2 + (y-y0)**2 + (z-z0)**2)
errfunc = lambda p, x: fitfunc(p, x) - p[3]
p1, flag = leastsq(errfunc, p0, args=(coords,))
>>> center
array([-39.77447344, -69.89096249, 44.46437355])
>>> R
array([ 69.87797469])
>>> p1
array([-39.77447344, -69.89096249, 44.46437355, 69.87797469])
@Adobe因为
coords
有shape(100,3)
,但是coords.T
有shape(3100)
,所以当你执行x,y,z=coords.T
时,它会将一行解压到每个变量中。哦,太酷了。我为simular做了zCoords=Coordinates[:,2]
。我明天会开一个赏金——我想奖励你的答案。
fitfunc = lambda p, x: sqrt(p[3]**2 - (x[:, 0] - p[0])**2 - (x[:, 1] - p[1])**2) + p[2]
import numpy as np
from scipy.optimize import leastsq
# test data: sphere centered at 'center' of radius 'R'
center = (np.random.rand(3) - 0.5) * 200
R = np.random.rand(1) * 100
coords = np.random.rand(100, 3) - 0.5
coords /= np.sqrt(np.sum(coords**2, axis=1))[:, None]
coords *= R
coords += center
p0 = [0, 0, 0, 1]
def fitfunc(p, coords):
x0, y0, z0, R = p
x, y, z = coords.T
return np.sqrt((x-x0)**2 + (y-y0)**2 + (z-z0)**2)
errfunc = lambda p, x: fitfunc(p, x) - p[3]
p1, flag = leastsq(errfunc, p0, args=(coords,))
>>> center
array([-39.77447344, -69.89096249, 44.46437355])
>>> R
array([ 69.87797469])
>>> p1
array([-39.77447344, -69.89096249, 44.46437355, 69.87797469])