的polyfit2d
下实现使用可用numpy的方法numpy.polynomial.polynomial.polyvander2d
和numpy.polynomial.polynomial.polyval2d
#!/usr/bin/env python3
import unittest
def polyfit2d(x, y, f, deg):
from numpy.polynomial import polynomial
import numpy as np
x = np.asarray(x)
y = np.asarray(y)
f = np.asarray(f)
deg = np.asarray(deg)
vander = polynomial.polyvander2d(x, y, deg)
vander = vander.reshape((-1,vander.shape[-1]))
f = f.reshape((vander.shape[0],))
c = np.linalg.lstsq(vander, f)[0]
return c.reshape(deg+1)
class MyTest(unittest.TestCase):
def setUp(self):
return self
def test_1(self):
self._test_fit(
[-1,2,3],
[ 4,5,6],
[[1,2,3],[4,5,6],[7,8,9]],
[2,2])
def test_2(self):
self._test_fit(
[-1,2],
[ 4,5],
[[1,2],[4,5]],
[1,1])
def test_3(self):
self._test_fit(
[-1,2,3],
[ 4,5],
[[1,2],[4,5],[7,8]],
[2,1])
def test_4(self):
self._test_fit(
[-1,2,3],
[ 4,5],
[[1,2],[4,5],[0,0]],
[2,1])
def test_5(self):
self._test_fit(
[-1,2,3],
[ 4,5],
[[1,2],[4,5],[0,0]],
[1,1])
def _test_fit(self, x, y, c, deg):
from numpy.polynomial import polynomial
import numpy as np
X = np.array(np.meshgrid(x,y))
f = polynomial.polyval2d(X[0], X[1], c)
c1 = polyfit2d(X[0], X[1], f, deg)
np.testing.assert_allclose(c1,
np.asarray(c)[:deg[0]+1,:deg[1]+1],
atol=1e-12)
unittest.main()
这是一个非常优雅的解决问题的方法。我已经使用你的建议代码来适应一个椭圆抛物面,稍微修改我想分享的内容。我感兴趣的是仅以“z = a *(x-x0)** 2 + b *(y-y0)** 2 + c”的形式拟合线性解。我的更改的完整代码可以在[这里]看到(http://www.nublia.com/dev/stackoverflow/stow_polyfit2d.py)。 – regeirk
注意:对于numpy的最新版本,请参阅下面的@ klaus的答案。在我原来的答案'polyvander2d'等时不存在,但他们现在是要走的路。 –
这真的是一个三阶多项式吗?除非我对它有错误的理解,但是它不会有第6项的“X ** 3 * Y ** 3”这个词吗? – maxymoo