2009-06-22 6 views
11

Y at-il un meilleur moyen de trouver ce qui X me donne le Y Je cherche SciPy? J'ai juste commencé à utiliser SciPy et je ne connais pas très bien chaque fonction.Interpolation dans SciPy: Trouver X qui produit Y

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 
+0

Pouvez-vous préciser ce que vous voulez mieux? Performance, précision, concision? – Ryan

Répondre

16

La classe UnivariateSpline dans scipy rend les splines beaucoup plus pythoniques.

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)) 

Pour trouver x à y faire alors:

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

Je pensais que interpoler x en termes de y pourrait fonctionner mais il faut une voie quelque peu différente. Il pourrait être plus proche avec plus de points.

+1

Cela ne nécessiterait-il pas deux fois la quantité de calculs de l'UC, puisque l'interpolation pratiquement deux fois du même jeu de données? – JcMaco

+0

@JcMaco, la première utilisation de UnivariateSpline est juste de faire une jolie intrigue. Le deuxième usage est ce qui donne réellement les valeurs. – Theran

+0

Craig a raison, pouvez-vous corriger sur votre exemple car c'est génial! –

1

Si vous avez besoin est une interpolation linéaire, vous pouvez utiliser la fonction interp dans numpy.

+0

Je préfère l'interpolation spline. Comment la fonction interp pourrait-elle m'aider à résoudre mon problème plus facilement? – JcMaco

+0

Votre question ne précisait pas le type d'interpolation dont vous aviez besoin - si linéaire n'est pas assez bon pour votre problème, je ne pense pas qu'interp puisse vous aider. –

0

J'ai peut-être mal compris votre question, si oui, je suis désolé. Je ne pense pas que vous devez utiliser SciPy. NumPy a une fonction des moindres carrés.

#!/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)) 

Cela retournera [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 out, pas mal

+0

Le problème est de trouver quel numéro me donnera 52.21. Bien sûr, il peut y avoir beaucoup de solutions si l'interpolation est quadratique (ou puissance supérieure). – JcMaco

Questions connexes