SciPy中的插值:如何找到产生Y的X

15 投票
3 回答
14071 浏览
提问于 2025-04-15 12:25

有没有更好的方法来找到哪个 X 能让我得到我想要的 Y,在使用 SciPy 的时候?我刚开始用 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

3 个回答

0

我可能误解了你的问题,如果是这样我很抱歉。我觉得你不需要使用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,挺不错的。

3

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

19

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会有效果,但其实这个方法有点不同。如果用更多的点,结果可能会更接近。

撰写回答