【问题标题】:Interpolation in SciPy: Finding X that produces YSciPy 中的插值:找到产生 Y 的 X
【发布时间】:2010-11-04 23:29:24
【问题描述】:

有没有更好的方法来找到哪个 X 给了我我在 SciPy 中寻找的 Y?我刚开始使用 SciPy,对每个功能都不太熟悉。

import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate

x = [70, 80, 90, 100, 110]
y = [49.7, 80.6, 122.5, 153.8, 163.0]
tck = interpolate.splrep(x,y,s=0)
xnew = np.arange(70,111,1)
ynew = interpolate.splev(xnew,tck,der=0)
plt.plot(x,y,'x',xnew,ynew)
plt.show()
t,c,k=tck
yToFind = 140
print interpolate.sproot((t,c-yToFind,k)) #Lowers the spline at the abscissa

【问题讨论】:

  • 你能详细说明你想变得更好吗?性能、准确性、简洁性?

标签: python numpy scipy interpolation scientific-computing


【解决方案1】:

scipy 中的 UnivariateSpline 类使样条曲线更加 Python 化。

x = [70, 80, 90, 100, 110]
y = [49.7, 80.6, 122.5, 153.8, 163.0]
f = interpolate.UnivariateSpline(x, y, s=0)
xnew = np.arange(70,111,1)

plt.plot(x,y,'x',xnew,f(xnew))

要在 y 处找到 x,然后执行:

yToFind = 140
yreduced = np.array(y) - yToFind
freduced = interpolate.UnivariateSpline(x, yreduced, s=0)
freduced.roots()

我认为根据 y 对 x 进行插值可能会奏效,但它采取的路线有所不同。积分越多,距离可能越近。

【讨论】:

  • 这是否需要两倍的 CPU 计算量,因为实际上对相同的数据集进行了两次插值?
  • @JcMaco,UnivariateSpline的第一次使用只是为了制作一个漂亮的情节。第二种用法是实际给出的值。
  • 克雷格是对的,你能在你的例子中纠正它吗?否则它很棒!
  • 修正了错字。谢谢克雷格。
【解决方案2】:

如果你只需要线性插值,你可以使用 numpy 中的interp 函数。

【讨论】:

  • 我更喜欢样条插值。 interp 函数如何帮助我更轻松地解决问题?
  • 你的问题没有说明你需要什么类型的插值——如果线性不足以解决你的问题,那么我认为 interp 不会有帮助。
【解决方案3】:

我可能误解了你的问题,如果是这样,我很抱歉。我认为您不需要使用 SciPy。 NumPy 有一个最小二乘函数。

#!/usr/bin/env python

from numpy.linalg.linalg import lstsq



def find_coefficients(data, exponents):
    X = tuple((tuple((pow(x,p) for p in exponents)) for (x,y) in data))
    y = tuple(((y) for (x,y) in data))
    x, resids, rank, s = lstsq(X,y)
    return x

if __name__ == "__main__":
    data = tuple((
        (1.47, 52.21),
        (1.50, 53.12),
        (1.52, 54.48),
        (1.55, 55.84),
        (1.57, 57.20),
        (1.60, 58.57),
        (1.63, 59.93),
        (1.65, 61.29),
        (1.68, 63.11),
        (1.70, 64.47),
        (1.73, 66.28),
        (1.75, 68.10),
        (1.78, 69.92),
        (1.80, 72.19),
        (1.83, 74.46)
    ))
    print find_coefficients(data, range(3))

这将返回 [128.81280358 -143.16202286 61.96032544]。

>>> x=1.47 # the first of the input data
>>> 128.81280358 + -143.16202286*x + 61.96032544*(x**2)
52.254697219095988

0.04 出,还不错

【讨论】:

  • 问题是找到哪个数字会给我 52.21。当然,如果插值是二次的(或更高的幂),则可以有很多解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多