Seite 1 von 1

Scipy Interpolation

Verfasst: Freitag 17. November 2017, 18:32
von Simon123
Hallo zusammen,

wie kann ich eine Funktion die ich interpoliert habe über die Interpolationsgrenzen hinaus erweitern. Hier mal ein kleiner Programm fetzen der das Problem skizzieren soll.

import numpy as np
from scipy import interpolate

r=np.arange(1,3,0.5)
f=2*r

interp=interpolate.interp1d(x_f,y_f,kind="linear")

Jetzt möche ich erreichen dass die Funktion auch über diese Grenzen hinaus definiert ist. Im Prinzip soll die Funktion folgende Form haben
1, für 0<r<1
f, für 1<r<3
2 für 3<r<5
0 sonst

Da ich später als Argument der Funktion einen mehrdimensionalen Array einsetzen will, kann ich es nicht mit einer einfachen else if Funktion lösen.

Vielen Dank und viele Grüße,

Simon

Re: Scipy Interpolation

Verfasst: Freitag 17. November 2017, 21:32
von noisefloor
Hallo,

ich bin nicht sicher, ob ich deine Frage richtig verstehe, aber so:

[codebox=pycon file=Unbenannt.txt]>>> interp=interpolate.interp1d(r,f,kind="linear", fill_value="extrapolate")
>>> interp(0.5)
array(1.0)
>>>[/code]
bekommst du doch Werte, die außerhalb der Grenzen liegen (im Beispiel für r=0.5).

Gruß, noisefloor

P.S.: Willkommen im Forum :-)

Re: Scipy Interpolation

Verfasst: Samstag 18. November 2017, 17:29
von Simon123
Hi,

danke für deine Hilfe. Die Funktion mit extrapolate habe ich auch schon ausprobiert und im Prinzip ist das genau das, was ich brauche. Wende ich die nämlich auf meinen 1000*1000 großen Array an funktioniert die Sache. Problem ist nur, dass ich die Werte über die Grenzen hinaus auf einen bestimmten konstanten Wert festsetzen muss. Im Prinzip könnte ich das ja eben mit einer einfachen If else Funktion machen, wo mir dann aber der mehrdimensionale Array Probleme macht. Hängt die Funktion nur von dem Parameter r ab ( entlang dem ich interpoliert habe also
interp=interpolate.interp1d(f,r,kind="linear")), konnte ich das Problem mit folgender Funktion lösen:

def apply_f_to_grid(x,f_linear_interp,lower_interp_limit,upper_interp_limit,value_below_interp_limit,value_above_interp_limit,upper_limit_0):
cond1= x < lower_interp_limit
cond2= x <= upper_interp_limit
cond3= x <= upper_limit_0

a1=x*0 #same structure as x but empty
a1[cond1]=value_below_interp_limit

a2=0*x
a2[(~cond1) & (cond2)]=f_linear_interp(x[(~cond1) & (cond2)])

a3=0*x
a3[(~cond2)&(cond3)]=value_above_interp_limit

return a1+a2+a3

Hierbei kann ich nun für x den 1000*1000 Array einsetzen. Als weiteres Problem hatte ich jetzt, dass meine Funktion f(r) an einem bestimmten Wert nicht einfach nur eine Zahle ist, sondern wieder ein Array mit 100 Einträgen weshalb die Funktion apply_f_to_grid nicht mehr funktioniert.
Im Prinzip könnte ich mir die Funktion sparen wenn ich eine Funktion vom Typ erhalte wie interp=interpolate.interp1d(r,f,kind="linear", fill_value="extrapolate"), nur das ich eben die Werte an den Rändern selbst setzen möchte. Dazu brauchte ich aber wohl eine spezielle numpy oder scipy Funktion. Die Alternative dazu ist, dass ich die Funktion apply_f_to_gri für diese 100 Werte einzeln Auswerte mit einer for Schleife was natürlich sehr langsam wird oder ich eine Möglichkeit finde wie Numpy/Sicpy das schneller erledigt.

Viele Grüße,
Simon

Re: Scipy Interpolation

Verfasst: Samstag 18. November 2017, 17:43
von narpfel
@Simon123: Du suchst `numpy.piecewise`.

Bitte setze Quellcode in Codebox-Tags („Code auswählen“ direkt über dem Textfeld), sonst ist er nicht lesbar.