2009-06-22 13 views
11

C'è un modo migliore per trovare quale X mi dà il Y Sto cercando in SciPy? Ho appena iniziato a usare SciPy e non ho molta familiarità con ciascuna funzione.Interpolazione in SciPy: trovare X che produce 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

Puoi approfondire ciò che si vuole essere meglio? Prestazioni, precisione, concisione? – Ryan

risposta

16

La classe UnivariateSpline in scipy rende le spline molto più pitone.

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

Per trovare x in y poi fare:

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

ho pensato interpolando x in termini di y potrebbe funzionare, ma ci vuole un percorso un po 'diverso. Potrebbe essere più vicino con più punti.

+1

Non richiederebbe due volte la quantità di calcoli della CPU poiché interpola praticamente lo stesso set di dati due volte? – JcMaco

+0

@JcMaco, il primo utilizzo di UnivariateSpline è solo per fare una bella trama. Il secondo utilizzo è ciò che dà effettivamente i valori. – Theran

+0

Craig ha ragione, puoi correggerlo sul tuo esempio perché altrimenti sarebbe fantastico! –

1

Se tutto ciò che serve è l'interpolazione lineare, è possibile utilizzare la funzione interp in NumPy.

+0

Preferisco l'interpolazione spline. In che modo la funzione interp può aiutarmi a risolvere il mio problema più facilmente? – JcMaco

+0

La tua domanda non ha specificato quale tipo di interpolazione ti serviva - se lineare non è abbastanza buono per il tuo problema, allora non credo che interp possa aiutarti. –

0

Forse ho frainteso la tua domanda, se è così mi dispiace. Non penso che tu debba usare SciPy. NumPy ha una funzione di minimi quadrati.

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

Questo restituirà [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, non male

+0

Il problema è trovare quale numero mi darà 52.21. Naturalmente, ci possono essere molte soluzioni se l'interpolazione è quadratica (o maggiore potenza). – JcMaco

Problemi correlati