Python 为什么numpy';s polyfit和polyval期望多项式系数的顺序相反?

Python 为什么numpy';s polyfit和polyval期望多项式系数的顺序相反?,python,numpy,Python,Numpy,我使用numpy的polyfit来拟合一些噪声数据,然后想使用polyval来评估一些新点的拟合。出于某种原因,拟合效果很好,但只有当我颠倒多项式系数的顺序时,polyval才能给出正确的结果: import numpy as np import numpy.polynomial.polynomial as poly import matplotlib.pyplot as plt # a noisy line x = np.linspace(0, 10, 100) y = x + np.ran

我使用numpy的
polyfit
来拟合一些噪声数据,然后想使用
polyval
来评估一些新点的拟合。出于某种原因,拟合效果很好,但只有当我颠倒多项式系数的顺序时,
polyval
才能给出正确的结果:

import numpy as np
import numpy.polynomial.polynomial as poly
import matplotlib.pyplot as plt

# a noisy line
x = np.linspace(0, 10, 100)
y = x + np.random.normal(0, 1, x.shape)

# calculate fit polynomial
fit_coeffs_poly = poly.polyfit(x, y, deg=1)
fit_polynomial_poly = poly.Polynomial(fit_coeffs_poly)(x)

# plot to check fit 
plt.plot(x, y, label='noisy')
plt.plot(x, fit_polynomial_poly, '-r', label='polyfit')
plt.legend(loc='lower right')
plt.show()
合身看起来不错:

polyval
仅在系数反转时才起作用:

>>> for i in range(0, 10):
>>>    print(np.polyval(fit_coeffs_poly, i))

0.9792056688016727
1.139755470535941
1.3003052722702093
1.4608550740044774
1.6214048757387456
1.781954677473014
1.9425044792072823
2.1030542809415502
2.2636040826758186
2.424153884410087

>>> for i in range(0, 10):
>>>    print(np.polyval(fit_coeffs_poly[::-1], i))

0.16054980173426825
1.139755470535941
2.1189611393376135
3.0981668081392866
4.077372476940959
5.056578145742631
6.035783814544304
7.0149894833459765
7.9941951521476495
8.973400820949323

我忍不住觉得这是错的,他们倒退是没有意义的

我在周围挖了很多,发现了发生的事情。事实证明,numpy有两套多项式工具,一套在基本numpy库中,另一套在
numpy.polymone
中,它们的预期顺序相反。在两个库中都可以找到
polyfit
polyval
,在这个简单的情况下,它们的操作似乎相同,但它们的参数不同:

numpy

def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
def polyval(p, x)
polyfit
polyval
都期望并返回从高到低的多项式系数

numpy.polymone

def polyfit(x, y, deg, rcond=None, full=False, w=None)
def polyval(x, c, tensor=True) 
polyfit
polyval
都期望并返回从低到高的多项式系数。还请注意,
polyval
要求参数的顺序不同

下面是一个快速演示:

import numpy as np
import numpy.polynomial.polynomial as poly
import matplotlib.pyplot as plt

# a noisy line
x = np.linspace(0, 10, 100)
y = x + np.random.normal(0, 1, x.shape)

# calculate fit polynomial with base numpy
fit_coeffs_np = np.polyfit(x, y, deg=1)
fit_polynomial_np = poly.Polynomial(fit_coeffs_np[::-1])(x)
print("numpy", fit_coeffs_np)

# calculate fit polynomial with numpy.polynomial.polynomial
fit_coeffs_poly = poly.polyfit(x, y, deg=1)
fit_polynomial_poly = poly.Polynomial(fit_coeffs_poly)(x)
print("poly", fit_coeffs_poly)

# test some values
for i in range(0, 10):
    print(np.polyval(fit_coeffs_np, i), poly.polyval(i, fit_coeffs_poly))

# make a nice plot
plt.xlabel('X')
plt.ylabel('Y')
plt.plot(x, y, label='noisy')
plt.plot(x, fit_polynomial_poly, '-g', label='np.poly')
plt.plot(x, fit_polynomial_np, '-r', label='np')
plt.legend(loc='lower right')
plt.text(0, 10, 'np: {}'.format(fit_coeffs_np))
plt.text(0, 9, 'np.poly: {}'.format(fit_coeffs_poly))
plt.savefig('good.png')
plt.show() 

这两者在名义上似乎是等同的,但你不能在没有意识到细微差别的情况下混搭

如果有人知道为什么有两种不同的实现,我很想知道

-0.009244843991578149 -0.009244843991576678
1.0080792020754397 1.0080792020754408
2.0254032481424575 2.025403248142458
3.042727294209475 3.0427272942094756
4.060051340276494 4.060051340276493
5.077375386343512 5.07737538634351
6.094699432410529 6.094699432410528
7.112023478477547 7.112023478477545
8.129347524544565 8.129347524544563
9.146671570611582 9.14667157061158