插值 Python
Interpolation Python
我的问题很简单,但是我似乎找不到快速的解决方案。
我想插入定义在 x_model
坐标
的 y_model
数组
x_model = np. array([ 400., 425., 450., 475., 500., 525., 550., 575., 600.,
625., 650., 675., 700.])
y_model = np.array([ 3.30395705e-03, 3.07586379e-03, 2.90207925e-03,
2.81385536e-03, 2.78152394e-03, 2.14072505e-03,
1.64075861e-03, 9.81255709e-04, 3.61950352e-04,
2.15834081e-04, 1.35457654e-04, 8.22104550e-05,
5.84126935e-05])
到新,x_data
坐标:
x_data = np.array([412., 443., 490., 510., 555., 670.])
所以我应该得到一个包含 6 个元素的简单一维 y-data
数组。
我想到了这样的事情,你怎么看?
from scipy import interpolate
f = interpolate.interp1d(x_model, y_model, kind = 'linear')
y_data = f(x_data)
最初根据主要提出的问题寻求解决方案,将问题限制为线性插值。
然而,在讨论过程中,一些作者正确地指出,对于这样的问题,线性拟合是不够的。
非线性曲线拟合应该更合适吗?
Numpy 具有 interp
功能,可以为您做到这一点。
您可以简单地调用:
y_data = np.interp(x_data,x_model,y_model)
您可以在此处找到 numpy.interp() 的文档:
https://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html
如果您希望能够检查线性回归并稍微调整一下,我建议您使用 scikit-learn's linear regression.
代码如下:
import numpy as np
from sklearn.linear_model import LinearRegression
x_model = np. array([ 400., 425., 450., 475., 500., 525., 550., 575., 600.,
625., 650., 675., 700.])
y_model = np.array([ 3.30395705e-03, 3.07586379e-03, 2.90207925e-03,
2.81385536e-03, 2.78152394e-03, 2.14072505e-03,
1.64075861e-03, 9.81255709e-04, 3.61950352e-04,
2.15834081e-04, 1.35457654e-04, 8.22104550e-05,
5.84126935e-05])
lr = LinearRegression()
lr.fit(x_model[:, None], y_model)
x_data = np.array([412., 443., 490., 510., 555., 670.])
y_data = lr.predict(x_data[:, None])
print(y_data)
请注意,我必须在拟合或预测时向 x
添加一个维度,因为线性回归需要一个二维数组。
执行此操作的 "scientific" 方法是将线性函数拟合到现有数据点,然后在新的 x_values 上计算该函数。这具有多个优点,包括可能使用每个数据点的不确定性,以及插值误差传播的可能性。 (f.e结合非常好的包'uncertainties')你也可以很容易地改变你的模型函数,它不一定是线性的,但可以是任何函数...
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
x_model = np. array([ 400., 425., 450., 475., 500., 525., 550., 575., 600., 625., 650., 675., 700.])
y_model = np.array([ 3.30395705e-03, 3.07586379e-03, 2.90207925e-03,
2.81385536e-03, 2.78152394e-03, 2.14072505e-03,
1.64075861e-03, 9.81255709e-04, 3.61950352e-04,
2.15834081e-04, 1.35457654e-04, 8.22104550e-05,
5.84126935e-05])
x_data = np.array([412., 443., 490., 510., 555., 670.])
def linFunc(x, k, d):
return k*x+d
cop, cov = curve_fit(linFunc, x_model, y_model)
xplot = np.linspace(min(x_model), max(x_model), 10**4)
plt.figure()
plt.plot(x_model, y_model, 'ro', label = 'original data')
plt.plot(xplot, linFunc(xplot, *cop), 'r--', label = "fittet function")
plt.plot(x_data, linFunc(x_data, *cop), 'bo', label = "interpolated values")
print(linFunc(x_data, *cop))
最简单的方法是使用最小二乘法拟合线性函数。
numpy 中的一个简单实现是 numpy.linalg.lstsq
.
然后,您可以将函数 lambda x: m*x+c
与计算出的斜率 m
和偏移量 c
结合使用,以获得任何 [=15= 的直线上的 [=14=] 值].
numpy 文档包含一个示例,这看起来与您问题中的示例几乎相同。
我上面的回答是针对线性插值的情况。
关于您从线性插值到一般插值的编辑:您需要知道您想要拟合什么函数。你假设你的数据是线性的吗?
您可以为每个点集拟合一个线性函数,但结果可能会很糟糕,要么因为没有线性关系,要么因为它是嘈杂的数据。如果不知道什么函数可能是合适的或噪声量有多大,您就无法轻松拟合函数。
对于高阶多项式也是如此,除了你可以将错误从欠拟合(非线性函数的线性回归)更改为过度拟合(具有与给定点匹配的过于复杂的函数,但是不适合插值)。
我的问题很简单,但是我似乎找不到快速的解决方案。
我想插入定义在 x_model
坐标
y_model
数组
x_model = np. array([ 400., 425., 450., 475., 500., 525., 550., 575., 600.,
625., 650., 675., 700.])
y_model = np.array([ 3.30395705e-03, 3.07586379e-03, 2.90207925e-03,
2.81385536e-03, 2.78152394e-03, 2.14072505e-03,
1.64075861e-03, 9.81255709e-04, 3.61950352e-04,
2.15834081e-04, 1.35457654e-04, 8.22104550e-05,
5.84126935e-05])
到新,x_data
坐标:
x_data = np.array([412., 443., 490., 510., 555., 670.])
所以我应该得到一个包含 6 个元素的简单一维 y-data
数组。
我想到了这样的事情,你怎么看?
from scipy import interpolate
f = interpolate.interp1d(x_model, y_model, kind = 'linear')
y_data = f(x_data)
最初根据主要提出的问题寻求解决方案,将问题限制为线性插值。 然而,在讨论过程中,一些作者正确地指出,对于这样的问题,线性拟合是不够的。
非线性曲线拟合应该更合适吗?
Numpy 具有 interp
功能,可以为您做到这一点。
您可以简单地调用:
y_data = np.interp(x_data,x_model,y_model)
您可以在此处找到 numpy.interp() 的文档: https://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html
如果您希望能够检查线性回归并稍微调整一下,我建议您使用 scikit-learn's linear regression. 代码如下:
import numpy as np
from sklearn.linear_model import LinearRegression
x_model = np. array([ 400., 425., 450., 475., 500., 525., 550., 575., 600.,
625., 650., 675., 700.])
y_model = np.array([ 3.30395705e-03, 3.07586379e-03, 2.90207925e-03,
2.81385536e-03, 2.78152394e-03, 2.14072505e-03,
1.64075861e-03, 9.81255709e-04, 3.61950352e-04,
2.15834081e-04, 1.35457654e-04, 8.22104550e-05,
5.84126935e-05])
lr = LinearRegression()
lr.fit(x_model[:, None], y_model)
x_data = np.array([412., 443., 490., 510., 555., 670.])
y_data = lr.predict(x_data[:, None])
print(y_data)
请注意,我必须在拟合或预测时向 x
添加一个维度,因为线性回归需要一个二维数组。
执行此操作的 "scientific" 方法是将线性函数拟合到现有数据点,然后在新的 x_values 上计算该函数。这具有多个优点,包括可能使用每个数据点的不确定性,以及插值误差传播的可能性。 (f.e结合非常好的包'uncertainties')你也可以很容易地改变你的模型函数,它不一定是线性的,但可以是任何函数...
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
x_model = np. array([ 400., 425., 450., 475., 500., 525., 550., 575., 600., 625., 650., 675., 700.])
y_model = np.array([ 3.30395705e-03, 3.07586379e-03, 2.90207925e-03,
2.81385536e-03, 2.78152394e-03, 2.14072505e-03,
1.64075861e-03, 9.81255709e-04, 3.61950352e-04,
2.15834081e-04, 1.35457654e-04, 8.22104550e-05,
5.84126935e-05])
x_data = np.array([412., 443., 490., 510., 555., 670.])
def linFunc(x, k, d):
return k*x+d
cop, cov = curve_fit(linFunc, x_model, y_model)
xplot = np.linspace(min(x_model), max(x_model), 10**4)
plt.figure()
plt.plot(x_model, y_model, 'ro', label = 'original data')
plt.plot(xplot, linFunc(xplot, *cop), 'r--', label = "fittet function")
plt.plot(x_data, linFunc(x_data, *cop), 'bo', label = "interpolated values")
print(linFunc(x_data, *cop))
最简单的方法是使用最小二乘法拟合线性函数。
numpy 中的一个简单实现是 numpy.linalg.lstsq
.
然后,您可以将函数 lambda x: m*x+c
与计算出的斜率 m
和偏移量 c
结合使用,以获得任何 [=15= 的直线上的 [=14=] 值].
numpy 文档包含一个示例,这看起来与您问题中的示例几乎相同。
我上面的回答是针对线性插值的情况。
关于您从线性插值到一般插值的编辑:您需要知道您想要拟合什么函数。你假设你的数据是线性的吗?
您可以为每个点集拟合一个线性函数,但结果可能会很糟糕,要么因为没有线性关系,要么因为它是嘈杂的数据。如果不知道什么函数可能是合适的或噪声量有多大,您就无法轻松拟合函数。
对于高阶多项式也是如此,除了你可以将错误从欠拟合(非线性函数的线性回归)更改为过度拟合(具有与给定点匹配的过于复杂的函数,但是不适合插值)。