Scipy Interpolation

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Simon123
User
Beiträge: 7
Registriert: Freitag 17. November 2017, 18:17

Freitag 17. November 2017, 18:32

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
Benutzeravatar
noisefloor
User
Beiträge: 2427
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Freitag 17. November 2017, 21:32

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 :-)
Simon123
User
Beiträge: 7
Registriert: Freitag 17. November 2017, 18:17

Samstag 18. November 2017, 17:29

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
narpfel
User
Beiträge: 213
Registriert: Freitag 20. Oktober 2017, 16:10

Samstag 18. November 2017, 17:43

@Simon123: Du suchst `numpy.piecewise`.

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