Numpy 如何拟合三维数据

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,

我有一个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, 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])