在python中尝试线性插值

在python中尝试线性插值,python,scipy,interpolation,Python,Scipy,Interpolation,我有3个数组:a、b、c,它们的长度都是15 a=[950, 850, 750, 675, 600, 525, 460, 400, 350, 300, 250, 225, 200, 175, 150] b = [16, 12, 9, -35, -40, -40, -40, -45, -50, -55, -60, -65, -70, -75, -80] c=[32.0, 22.2, 12.399999999999999, 2.599999999999998, -7.2000000000000

我有3个数组:a、b、c,它们的长度都是15

a=[950, 850, 750, 675, 600, 525, 460, 400, 350, 300, 250, 225, 200, 175, 150] 

b = [16, 12, 9, -35, -40, -40, -40, -45, -50, -55, -60, -65, -70, -75, -80]

c=[32.0, 22.2, 12.399999999999999, 2.599999999999998, -7.200000000000003, -17.0, -26.800000000000004, -36.60000000000001, -46.400000000000006, -56.2, -66.0, -75.80000000000001, -85.60000000000001, -95.4, -105.20000000000002] 
我试图在b=c的索引处找到a的值。T

问题是没有精确的b=c的位置,所以我需要在数组中的值之间进行线性插值,以找到a的值,其中b=c。这有意义吗

我正在考虑使用scipy.interpolate进行插值


我正绞尽脑汁想如何解决这个问题。任何关于这方面的想法都会很棒

以下是函数的简单变体:

该函数可与
t=a
y=b-c
一起使用。例如,以下是作为numpy数组输入的数据:

In [354]: a = np.array([950, 850, 750, 675, 600, 525, 460, 400, 350, 300, 250, 225, 200, 175, 150])

In [355]: b = np.array([16, 12, 9, -35, -40, -40, -40, -45, -50, -55, -60, -65, -70, -75, -80])

In [356]: c = np.array([32.0, 22.2, 12.399999999999999, 2.599999999999998, -7.200000000000003, -17.0, -26.800000000000004, -3
     ...: 6.60000000000001, -46.400000000000006, -56.2, -66.0, -75.80000000000001, -85.60000000000001, -95.4, -105.2000000000
     ...: 0002])
“b=c”的位置是“b-c=0”的位置,因此我们将
b-c
传递给
y

In [357]: find_roots(a, b - c)
Out[357]: array([ 312.5])
因此
a
的线性插值为312.5

使用以下matplotlib命令:

In [391]: plot(a, b, label="b")
Out[391]: [<matplotlib.lines.Line2D at 0x11eac8780>]

In [392]: plot(a, c, label="c")
Out[392]: [<matplotlib.lines.Line2D at 0x11f23aef0>]

In [393]: roots = find_roots(a, b - c)

In [394]: [axvline(root, color='k', alpha=0.2) for root in roots]
Out[394]: [<matplotlib.lines.Line2D at 0x11f258208>]

In [395]: grid()

In [396]: legend(loc="best")
Out[396]: <matplotlib.legend.Legend at 0x11f260ba8>

In [397]: xlabel("a")
Out[397]: <matplotlib.text.Text at 0x11e71c470>
[391]中的
:绘图(a,b,label=“b”)
Out[391]:[]
在[392]中:绘图(a,c,label=“c”)
出[392]:[]
在[393]中:根=查找_根(a,b-c)
在[394]中:[axvline(root,color='k',alpha=0.2)表示根中的根]
出[394]:[]
在[395]:grid()中
在[396]中:图例(loc=“best”)
出[396]:
在[397]中:xlabel(“a”)
出[397]:
我知道情节


另一个简单的解决方案使用:

  • 每个向量一个线性回归器(使用scikit learn完成,因为我的scipy文档已停止;很容易切换到基于numpy/scipy的线性回归)
  • 通用最小化
代码 输出 情节
这不一定能解决您的问题,因为您的数据似乎不是线性的,但它可能会给您一些想法。如果您假设a、b和c线是线性的,那么以下想法可行:

对直线a、b和c进行线性回归,以获得其各自的斜率(m_a、m_b、m_c)和y截距(b_a、b_b、b_c)。然后解出x的方程‘y_b=y_c’,然后找到y=m_a*x+b_a得到你的结果

由于线性回归近似求解y=m*x+b,因此方程y_b=y_c可通过手工计算得到:x=(b_b-b_c)/(m_c-m_b)

使用python,您可以获得:

>> m_a, b_a, r_a, p_a, err_a = stats.linregress(range(15), a)
>> m_b, b_b, r_b, p_b, err_b = stats.linregress(range(15), b)
>> m_c, b_c, r_c, p_c, err_c = stats.linregress(range(15), c)
>> x = (b_b-b_c) / (m_c-m_b)
>> m_a * x + b_a
379.55151515151516
由于数据不是线性的,所以可能需要逐个遍历向量并搜索重叠的y间隔。然后可以应用上述方法,但仅使用两个区间的端点来构造线性回归的b和c输入。在这种情况下,您应该得到一个精确的结果,因为最小二乘法将仅使用两个点进行完美插值(尽管有更有效的方法,因为在有两条直线的简单情况下,可以精确求解交点)


干杯。

你能添加一些数组的例子吗
a
b
c
b=[16,12,9,-35,-40,-40,-45,-50,-55,-60,-65,-70,-75,-80])
c=[32.0,22.2,12.39999999999999,2.599999999999998,-72000000000003,-17.0,-2680000000000004,-366000000000001,-46400000000000006,-56.2,-66.0,-75800000000001,-856000000000001,-95.4,-105200000000002]
a=[9508507506756750600525460400350300250225200175150]定义
线性插值
(你的意思是什么?所有点的线性回归;分段线性?这是关于数据的有效假设吗?..)。另外:不要将此示例添加为注释,而是编辑你的问题并将其格式设置得很好!线性插值:。特别是,请参阅“数据集的线性插值”:酷,但是379?绘制数据,看看你是否觉得这个答案令人满意。@WarrenWeckesser这都是关于模型的。我问他线性插值是什么意思,但没有得到答案。所以我的方法是使用全局线性回归。这可能有效,也可能无效。这是一个模型决定!所以我必须承认:我觉得它令人满意,人们可以sily看到了我们模型之间的差异(现在你也添加了一个绘图)。不要让Warren看到你的解决方案;-)。我喜欢它。虽然这是有争议的,如果线性回归是正确的方法(你质疑过),OP没有给出太多信息。我们的方法是相同的,有相同的结果,但你的方法更优雅(不需要通用优化器)!
a=[950, 850, 750, 675, 600, 525, 460, 400, 350, 300, 250, 225, 200, 175, 150]
b = [16, 12, 9, -35, -40, -40, -40, -45, -50, -55, -60, -65, -70, -75, -80]
c=[32.0, 22.2, 12.399999999999999, 2.599999999999998, -7.200000000000003, -17.0, -26.800000000000004, -36.60000000000001, -46.400000000000006, -56.2, -66.0, -75.80000000000001, -85.60000000000001, -95.4, -105.20000000000002]

from sklearn.linear_model import LinearRegression
from scipy.optimize import minimize
import numpy as np

reg_a = LinearRegression().fit(np.arange(len(a)).reshape(-1,1), a)
reg_b = LinearRegression().fit(np.arange(len(b)).reshape(-1,1), b)
reg_c = LinearRegression().fit(np.arange(len(c)).reshape(-1,1), c)

funA = lambda x: reg_a.predict(x.reshape(-1,1))
funB = lambda x: reg_b.predict(x.reshape(-1,1))
funC = lambda x: reg_c.predict(x.reshape(-1,1))

opt_crossing = lambda x: (funB(x) - funC(x))**2
x0 = 1
res = minimize(opt_crossing, x0, method='SLSQP', tol=1e-6)
print(res)
print('Solution: ', funA(res.x))

import matplotlib.pyplot as plt

x = np.linspace(0, 15, 100)
a_ = reg_a.predict(x.reshape(-1,1))
b_ = reg_b.predict(x.reshape(-1,1))
c_ = reg_c.predict(x.reshape(-1,1))

plt.plot(x, a_, color='blue')
plt.plot(x, b_, color='green')
plt.plot(x, c_, color='cyan')
plt.scatter(np.arange(15), a, color='blue')
plt.scatter(np.arange(15), b, color='green')
plt.scatter(np.arange(15), c, color='cyan')

plt.axvline(res.x, color='red', linestyle='solid')
plt.axhline(funA(res.x), color='red', linestyle='solid')

plt.show()
fun: array([  7.17320622e-15])
jac: array([ -3.99479864e-07,   0.00000000e+00])
message: 'Optimization terminated successfully.'
nfev: 8
nit: 2
njev: 2
status: 0
success: True
  x: array([ 8.37754008])
Solution:  [ 379.55151658]
>> m_a, b_a, r_a, p_a, err_a = stats.linregress(range(15), a)
>> m_b, b_b, r_b, p_b, err_b = stats.linregress(range(15), b)
>> m_c, b_c, r_c, p_c, err_c = stats.linregress(range(15), c)
>> x = (b_b-b_c) / (m_c-m_b)
>> m_a * x + b_a
379.55151515151516