Python-4D lineare interpolation auf einem rechteckigen Gitter
Ich muss interpolieren-Temperatur-Daten Linear in 4 Dimensionen (Breite, Länge, Höhe und Zeit).
Die Anzahl der Punkte, die ziemlich hoch ist (360x720x50x8) und ich brauche eine schnelle Methode der Berechnung der Temperatur an jedem Punkt in Raum und Zeit innerhalb der Daten Grenzen gesetzt.
Habe ich versucht, mit scipy.interpolate.LinearNDInterpolator
aber mit Qhull für die triangulation ist ineffizient auf einem rechteckigen Gitter und dauert Stunden.
Durch das Lesen dieses SciPy ticket, die Lösung schien zu sein, die Umsetzung eines neuen nd-interpolator unter Verwendung der standard - interp1d
zu berechnen, eine höhere Anzahl der Daten-Punkte, und verwenden Sie dann eine "nearest neighbor" - Ansatz, mit dem neuen Datensatz.
Diese allerdings dauert wieder eine lange Zeit (Minuten).
Gibt es einen schnellen Weg von interpolierenden Daten auf einem rechteckigen Gitter in 4 Dimensionen ohne es dauert wenige Minuten, zu erreichen?
Ich daran gedacht, mit interp1d
4 mal ohne Berechnung eine höhere Dichte der Punkte, aber so dass es für den Benutzer zu nennen, mit den Koordinaten, aber ich kann nicht meinen Kopf herum, wie dies zu tun.
Sonst wäre das schreiben meiner eigenen 4D-interpolator, der speziell für meine Bedürfnisse eine option hier?
Hier ist der code, den ich benutzt habe um dies zu testen:
Mit scipy.interpolate.LinearNDInterpolator
:
import numpy as np
from scipy.interpolate import LinearNDInterpolator
lats = np.arange(-90,90.5,0.5)
lons = np.arange(-180,180,0.5)
alts = np.arange(1,1000,21.717)
time = np.arange(8)
data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))
coords = np.zeros((len(lats),len(lons),len(alts),len(time),4))
coords[...,0] = lats.reshape((len(lats),1,1,1))
coords[...,1] = lons.reshape((1,len(lons),1,1))
coords[...,2] = alts.reshape((1,1,len(alts),1))
coords[...,3] = time.reshape((1,1,1,len(time)))
coords = coords.reshape((data.size,4))
interpolatedData = LinearNDInterpolator(coords,data)
Mit scipy.interpolate.interp1d
:
import numpy as np
from scipy.interpolate import LinearNDInterpolator
lats = np.arange(-90,90.5,0.5)
lons = np.arange(-180,180,0.5)
alts = np.arange(1,1000,21.717)
time = np.arange(8)
data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))
interpolatedData = np.array([None, None, None, None])
interpolatedData[0] = interp1d(lats,data,axis=0)
interpolatedData[1] = interp1d(lons,data,axis=1)
interpolatedData[2] = interp1d(alts,data,axis=2)
interpolatedData[3] = interp1d(time,data,axis=3)
Danken Ihnen sehr für Ihre Hilfe!
- Ich habe keine Ahnung von python, aber Sie sollten look into quadrilineare oder quadricubic interpolation.
- Haben Sie Ideen, die in einer anderen Sprache zu diesem Thema? Dank
- Die Implementierung eines quadrilineare interpolation für einen einzelnen Punkt sollte ziemlich einfach sein, in jeder Sprache.
- Nein, Sie sind nicht. 3 Dimensionen sind konstant (.5, .5, 1), aber die Höhe dimension ist nicht immer abgetastet an der gleichen Stelle daher das Gitter nicht regelmäßig auf dieser Achse.
- Nicht genau. Ich habe die Temperatur-Daten auf einem regelmäßigen Gitter von lats, lons, DRUCK und Zeit. Allerdings, ich mein Ziel ist es, eine Funktion, die ich anrufen kann auf diese Weise: getTemperature(lat,lon,ALT,Zeit). Was ich zu tun habe, ist die HÖHE, die Daten auf dem gleichen raster wie die Temperatur, so dass ein regelmäßiges Gitter von lats,lons,Druck,Zeit. Jetzt, meine Implementierung der Methode sieht, den Druck der indices der beiden am nächsten Höhe Werte für die gegebene lat,lon,Zeit. Dann setzt die Höhe der Werte und die zwei Druck-Indizes zum Aufbau des 4D hypertetrahedron in die Temperatur-matrix und interpolieren...
- Ist das schnell genug, der nd-interpolator benutzt du ?
- Ich bin mit scipy ist interpolieren.LinearNDInterpolator. Es IST derzeit so schnell, aber ich habe Angst, nicht genug.. Jedem Aufruf der Funktion dauert ca. 1.86 ms, aber ich muss es ausgeführt werden, etwa 50.000-mal in 5 Sekunden, d.h. max run time 0.1 ms. Ich habe die Optimierung des rest des Codes zu reduzieren, die Anzahl der Anforderungen, sondern verbessert auch dies würde definitiv helfen. Irgendwelche Vorschläge?
- Gut, wenn LinearND ist ~ 20 mal zu langsam, es musst gehen -- schwierig, etwas zu ändern, nachdem Sie haben Zeit hinein. Es ist langsam, weil 1) die äußere Schleife in python, 2) es nicht wissen, dass Sie Ihren lat lange Zeit sind homogen. Jetzt map_coordinates ist wirklich schnell auf-uniform-grids, < 1 usec siehe unten, also, wie können Sie konvertieren Sie Ihr problem zu einer einheitlichen raster ? Können Sie Vorverarbeiten der Daten, oder ändert es zwischen Abfragen ? (Zeit für eine neue Frage ?)
- Gibt es eine Methode, die auch extrapoliert?
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der gleichen ticket, das Sie verlinkt haben, es ist ein Beispiel für die Umsetzung dessen, was Sie nennen tensorprodukt-interpolation, zeigt den richtigen Weg zum nest rekursive Aufrufe
interp1d
. Dies entspricht quadrilineare interpolation wenn Sie die Standardeinstellungkind='linear'
parameter für Ihreinterp1d
's.Zwar mag dies gut genug sein, diese ist nicht linear interpoliert, und es wird höher sein, um Begriffe in der interpolation-Funktion, wie dieses Bild aus den wikipedia-Eintrag über Bilineare interpolation zeigt:
Diese kann sehr gut sein, gut genug für das, was Sie nach sind, aber es gibt Anwendungen, bei denen eine trianguliert, wirklich stückweise lineare, interpoaltion bevorzugt. Wenn Sie wirklich brauchen, gibt es eine einfache Art und Weise zu arbeiten, um die Langsamkeit von qhull.
Einmal
LinearNDInterpolator
eingerichtet, es gibt zwei Schritte, um zu kommen mit einer interpolierten Wert für einen gegebenen Punkt:Werden Sie wahrscheinlich nicht wollen, um Durcheinander mit barycentric coordinates, also besser verlassen, dass
LinearNDInterpolator
. Aber Sie weiß einige Dinge über die triangulation. Meist, weil Sie ein regelmäßiges raster, in jeder hypercube der triangulation ist die gleiche. So zu interpolieren, um einen einzelnen Wert, könnten Sie zuerst bestimmen, in dem Teilcube, der Ihre Stelle ist, bauen Sie einLinearNDInterpolator
mit der 16 Eckpunkte des Würfels, und es verwenden, um zu interpolieren Wert:Kann das nicht funktionieren auf vektorisierte Daten, denn das würde erfordern das speichern einer
LinearNDInterpolator
für jeden möglich Teilcube, und obwohl es wäre wahrscheinlich schneller als triangulation wird die ganze Sache, wäre es immer noch sehr langsam.LinearNDInterpolator
unterteilt, die (hyper -) Würfel in disjunkte (hyper -) Tetraeder Fliesen (hyper -) Würfel, und ja, wenn die Interpolation für einen bestimmten Punkt, es wird nur nicht-null-Gewichtungen für died + 1
Eckpunkte der (hyper -) Tetraeder umgebenden diesem Punkt, muss aber alle2**d
Ecken zu interpolieren, jeder Punkt innerhalb des Würfels in eine stückweise linear. Und es gibt mehr Möglichkeiten der Interpolation mit dem2**d
Eckpunkte anderen als multilineares, siehe diese Beispiele: hpl.hp.com/techreports/98/HPL-98-95.pdfinterpn( mode="linear")
undmap_coordinates
tun.interpn()
undRegularGridInterpolator
. Ausgehend von den Quell-code, die beide zu sein scheinen Synonym.scipy.ndimage.map_coordinates
ist ein nettes schnell-interpolator für uniform-grids (alle Boxen die gleiche Größe).
Sehen multivariate spline-interpolation-in-python-scipy auf SO
für eine klare Beschreibung.
Für non-uniform rechteckige Gitter, einen einfachen wrapper
Intergrid Karten /Waage non-uniform uniform-grids,
dann hat map_coordinates.
Auf einem 4d-test-Fall wie deiner dauert es etwa 1 µsec pro Abfrage:
map_coordinates
nicht tun können?intergrid
anderen. Ist das deine Frage ?map_coordinates
nicht umgehen können wie Sie ist.Für sehr ähnliche Dinge, die ich verwenden Wissenschaftliche.Funktionen.Interpolation.InterpolatingFunction.
Können Sie jetzt lassen Sie es an die Benutzer zu nennen, die
InterpolatingFunction
mit den Koordinaten:InterpolatingFunction
hat nette zusätzliche features, wie die integration und aufschneiden.Allerdings weiß ich nicht sicher, ob die interpolation linear ist. Sie würden schauen müssen, die im Modul Quelle zu finden, aus.