Der Zweck von meshgrid
besteht darin, ein rechteckiges Gitter aus einem Array von x-Werten und einem Array von y-Werten zu erstellen.
Wenn wir zum Beispiel ein Gitter erstellen möchten, bei dem wir bei jedem ganzzahligen Wert einen Punkt zwischen 0 und 4 sowohl in x- als auch in y-Richtung haben. Um ein rechteckiges Gitter zu erstellen, benötigen wir jede Kombination der Punkte x
und y
.
Das werden 25 Punkte sein, oder? Wenn wir also eine x- und y - Array für alle diese Punkte schaffen wollte, wir könnten die folgende tun.
x[0,0] = 0 y[0,0] = 0
x[0,1] = 1 y[0,1] = 0
x[0,2] = 2 y[0,2] = 0
x[0,3] = 3 y[0,3] = 0
x[0,4] = 4 y[0,4] = 0
x[1,0] = 0 y[1,0] = 1
x[1,1] = 1 y[1,1] = 1
...
x[4,3] = 3 y[4,3] = 4
x[4,4] = 4 y[4,4] = 4
Dies würde zu Folgendem x
und y
Matrizen führen, so dass die Paarung des entsprechenden Elements in jeder Matrix die x- und y-Koordinaten eines Punktes im Gitter ergibt.
x = 0 1 2 3 4 y = 0 0 0 0 0
0 1 2 3 4 1 1 1 1 1
0 1 2 3 4 2 2 2 2 2
0 1 2 3 4 3 3 3 3 3
0 1 2 3 4 4 4 4 4 4
Wir können diese dann zeichnen, um zu überprüfen, ob es sich um ein Raster handelt:
plt.plot(x,y, marker='.', color='k', linestyle='none')
Offensichtlich wird dies besonders für große Bereiche von x
und sehr mühsam y
. Stattdessen meshgrid
kann dies tatsächlich für uns generieren: Alles, was wir angeben müssen, sind die eindeutigen x
und y
Werte.
xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);
Wenn wir jetzt anrufen meshgrid
, erhalten wir automatisch die vorherige Ausgabe.
xx, yy = np.meshgrid(xvalues, yvalues)
plt.plot(xx, yy, marker='.', color='k', linestyle='none')
Die Erstellung dieser rechteckigen Gitter ist für eine Reihe von Aufgaben nützlich. In dem Beispiel, das Sie in Ihrem Beitrag angegeben haben, können Sie einfach eine Funktion ( sin(x**2 + y**2) / (x**2 + y**2)
) über einen Wertebereich für x
und abtasten y
.
Da diese Funktion in einem rechteckigen Raster abgetastet wurde, kann die Funktion jetzt als "Bild" dargestellt werden.
Zusätzlich kann das Ergebnis jetzt an Funktionen übergeben werden, die Daten auf einem rechteckigen Raster erwarten (dh contourf
)
xx
und nicht erklärtyy
. Der mysteriöse Teil für mich war, warum es diese beiden Ergebnisse zurückgibt und wie sie aussehen. Hai Phans Antwort ist dafür praktisch. Ich denke, das macht es der Einfachheit halber, da die Handlung zwei solche Parameter will.xx = [xvalues for y in yvalues]
yy = [[y for x in xvalues] for y in yvalues]
x
undy
rückwärts? Wenn Sie dies tunxx, yy = np.meshgrid(np.arange(4), np.arange(4))
, ist es das Gegenteil von dem, was Sie haben,x
undy
im ersten Teil der Antwort. Es entspricht der Reihenfolge der Ausgaben fürmgrid
, jedoch nicht dem Meshgrid. Diexx
sollte in x-Richtung zunehmen, Ihre jedoch in y-Richtung.Mit freundlicher Genehmigung von Microsoft Excel:
quelle
XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
np.vstack([XX.ravel(), YY.ravel()]).T
Eigentlich ist der Zweck von
np.meshgrid
bereits in der Dokumentation erwähnt:Der Hauptzweck besteht also darin, Koordinatenmatrizen zu erstellen.
Sie haben sich wahrscheinlich gerade gefragt:
Warum müssen wir Koordinatenmatrizen erstellen?
Der Grund, warum Sie Koordinatenmatrizen mit Python / NumPy benötigen, ist, dass es keine direkte Beziehung von Koordinaten zu Werten gibt, außer wenn Ihre Koordinaten mit Null beginnen und rein positive ganze Zahlen sind. Dann können Sie einfach die Indizes eines Arrays als Index verwenden. Wenn dies jedoch nicht der Fall ist, müssen Sie die Koordinaten neben Ihren Daten speichern. Hier kommen Gitter ins Spiel.
Angenommen, Ihre Daten sind:
Jeder Wert repräsentiert jedoch einen 2 Kilometer breiten Bereich horizontal und 3 Kilometer vertikal. Angenommen, Ihr Ursprung ist die obere linke Ecke und Sie möchten Arrays, die die Entfernung darstellen, die Sie verwenden könnten:
wo v ist:
und h:
Wenn Sie also zwei Indizes haben, sagen wir
x
undy
(deshalb ist der Rückgabewert vonmeshgrid
normalerweisexx
oderxs
anstelle vonx
in diesem Fallh
horizontal gewählt!), Können Sie die x-Koordinate des Punkts, die y-Koordinate des Punkts und die erhalten Wert an diesem Punkt durch Verwendung von:Das macht es viel einfacher, die Koordinaten zu verfolgen, und (was noch wichtiger ist) Sie können sie an Funktionen übergeben, die die Koordinaten kennen müssen.
Eine etwas längere Erklärung
Es wird jedoch
np.meshgrid
nicht oft direkt verwendet, meistens verwendet man nur eines von ähnlichen Objektennp.mgrid
odernp.ogrid
. Hiernp.mgrid
stellt dersparse=False
undnp.ogrid
dersparse=True
Fall dar (ich beziehe mich auf dassparse
Argument vonnp.meshgrid
). Beachten Sie, dass zwischennp.meshgrid
undnp.ogrid
und ein signifikanter Unterschied bestehtnp.mgrid
: Die ersten beiden zurückgegebenen Werte (wenn zwei oder mehr vorhanden sind) werden umgekehrt. Oft spielt dies keine Rolle, aber Sie sollten je nach Kontext aussagekräftige Variablennamen angeben.Zum Beispiel im Fall eines 2D-Gitters und
matplotlib.pyplot.imshow
es ist sinnvoll, das erste zurückgegebene Elementnp.meshgrid
x
und das zweite Element zu benennen,y
während es fürnp.mgrid
und umgekehrt istnp.ogrid
.np.ogrid
und spärliche GitterWie bereits gesagt, ist die Ausgabe im Vergleich zu umgekehrt
np.meshgrid
, deshalb habe ich sie entpackt alsyy, xx
stattxx, yy
:Dies sieht bereits nach Koordinaten aus, insbesondere nach den x- und y-Linien für 2D-Diagramme.
Visualisiert:
np.mgrid
und dichte / ausgearbeitete GitterGleiches gilt hier: Die Ausgabe ist umgekehrt im Vergleich zu
np.meshgrid
:Im Gegensatz zu
ogrid
diesen Arrays enthalten allexx
undyy
Koordinaten in -5 <= xx <= 5; -5 <= yy <= 5 Gitter.Funktionalität
Diese Funktionen sind nicht nur auf 2D beschränkt, sondern funktionieren auch für beliebige Dimensionen (es gibt eine maximale Anzahl von Argumenten für die Funktion in Python und eine maximale Anzahl von Dimensionen, die NumPy zulässt):
Auch wenn diese auch für 1D funktionieren, gibt es zwei (weitaus häufigere) Funktionen zur Erstellung von 1D-Gittern:
np.arange
np.linspace
Neben dem
start
undstop
Argumente unterstützt es auch dasstep
Argument (auch komplexe Schritte , die die Anzahl der Schritte dar):Anwendungen
Sie haben speziell nach dem Zweck gefragt, und tatsächlich sind diese Gitter äußerst nützlich, wenn Sie ein Koordinatensystem benötigen.
Zum Beispiel, wenn Sie eine NumPy-Funktion haben, die den Abstand in zwei Dimensionen berechnet:
Und Sie möchten die Entfernung jedes Punktes wissen:
Die Ausgabe wäre identisch, wenn man in einem dichten Gitter anstelle eines offenen Gitters passieren würde. NumPys Broadcasting macht es möglich!
Lassen Sie uns das Ergebnis visualisieren:
Und dies ist auch bei NumPys der Fall
mgrid
undogrid
wird sehr praktisch, da Sie damit die Auflösung Ihrer Gitter einfach ändern können:Da dies
imshow
jedoch nicht unterstütztx
undy
eingegeben wird, müssen die Ticks von Hand geändert werden. Es wäre wirklich praktisch, wenn es diex
undy
Koordinaten akzeptieren würde , oder?Mit NumPy ist es einfach, Funktionen zu schreiben, die sich auf natürliche Weise mit Gittern befassen. Darüber hinaus gibt es in NumPy, SciPy und matplotlib mehrere Funktionen, die erwarten, dass Sie das Raster passieren.
Ich mag Bilder, also lasst uns Folgendes erkunden
matplotlib.pyplot.contour
:Beachten Sie, wie die Koordinaten bereits richtig eingestellt sind! Das wäre nicht der Fall, wenn Sie nur in der
density
.Oder um ein weiteres lustiges Beispiel mit Astropiemodellen zu geben (diesmal interessieren mich die Koordinaten nicht sonderlich, ich verwende sie nur, um ein Raster zu erstellen ):
Obwohl das ist nur „für die Looks“ mehr Funktionen im Zusammenhang mit Funktionsmodellen und Einpassen (zum Beispiel
scipy.interpolate.interp2d
,scipy.interpolate.griddata
zeigt auch Beispiele unter Verwendungnp.mgrid
) in Scipy usw. erfordern Gitter. Die meisten davon arbeiten mit offenen und dichten Gittern, einige arbeiten jedoch nur mit einem von ihnen.quelle
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
- Sollte der erste Bereich nicht mit 2 und der zweite mit 3 multipliziert werden, da er 2 km horizontal und 3 km vertikal ist?Angenommen, Sie haben eine Funktion:
und Sie möchten zum Beispiel sehen, wie es im Bereich von 0 bis 2 * pi aussieht. Wie würdest du es machen? Da
np.meshgrid
kommt rein:und eine solche Handlung würde aussehen wie:
Ist
np.meshgrid
also nur eine Annehmlichkeit. Im Prinzip könnte das Gleiche getan werden durch:Aber dort müssen Sie sich Ihrer Dimensionen bewusst sein (nehmen wir an, Sie haben mehr als zwei ...) und der richtigen Sendung.
np.meshgrid
erledigt das alles für dich.Mit meshgrid können Sie auch Koordinaten zusammen mit den Daten löschen, wenn Sie beispielsweise eine Interpolation durchführen möchten, aber bestimmte Werte ausschließen möchten:
Wie würden Sie jetzt die Interpolation durchführen? Sie können geben
x
undy
zu einer Interpolationsfunktion wiescipy.interpolate.interp2d
so dass Sie einen Weg , müssen zu wissen , welche Koordinaten gelöscht wurden:und dann können Sie immer noch mit den "richtigen" Koordinaten interpolieren (versuchen Sie es ohne das Meshgrid und Sie werden viel zusätzlichen Code haben):
Mit dem ursprünglichen Netzgitter können Sie die Interpolation für das ursprüngliche Gitter erneut abrufen:
Dies sind nur einige Beispiele, bei denen ich das verwendet habe,
meshgrid
da es möglicherweise noch viel mehr gibt.quelle
xx
,yy
. Es war schwer zu verstehen, was sie sind und warum wir sie zur Berechnung der Funktion verwenden. Scheint, ich habe es verstanden. Wir wollen einige Funktionen basierend auf Koordinaten berechnen. Wir können so etwas schreiben:for x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)
Stattdessen berechnen wirz
andersz=sin([x,x,...,x]) + sin([y,y,..y])
. Korrigiere mich, wenn ich falsch liege!numpy
: Meshgrid oder Broadcasting. Wenn Sie keine Punkte verwerfen (siehe letzter Teil meiner Antwort), sind beide tatsächlich funktional gleichwertig. Broadcasting ist nur eine implizite Schleife über die zu sendende Dimension. Beachten Sie, dass ich zusätzliche Dimensionen verwendet[:,None]
und[None, :]
eingefügt habe, damit das Ergebnis korrekt übertragen wird. Ihr zweites Beispiel ist eher wiesin([[y],[y],..[y]])
interpolated_grid = interpolated(xx, yy)
- das funktioniert bei mir nicht, Fehler:x and y should both be 1-D arrays
Meshgrid hilft beim Erstellen eines rechteckigen Gitters aus zwei 1-D-Arrays aller Punktpaare aus den beiden Arrays.
Wenn Sie nun eine Funktion f (x, y) definiert haben und diese Funktion auf alle möglichen Punktkombinationen aus den Arrays 'x' und 'y' anwenden möchten, können Sie dies tun:
Wenn Ihre Funktion nur das Produkt aus zwei Elementen erzeugt, kann auf diese Weise ein kartesisches Produkt effizient für große Arrays erzielt werden.
Von hier verwiesen
quelle
Die Grundidee
Angesichts möglicher Werte x,
xs
, (man denke an die sie als zeckenMarkierungen auf der X-Achse eines Diagramms) und möglichen y Werteys
,meshgrid
erzeugt die entsprechende Menge von (x, y) Gitterpunkte --- analogset((x, y) for x in xs for y in yx)
. Wenn zum Beispielxs=[1,2,3]
undys=[4,5,6]
, würden wir den Satz von Koordinaten erhalten{(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}
.Form des Rückgabewerts
Die zurückgegebene Darstellung
meshgrid
unterscheidet sich jedoch in zweierlei Hinsicht vom obigen Ausdruck:Zuerst , um
meshgrid
die Gitterpunkte in einem 2D - Array aus legt: Reihen an unterschiedlichen y-Werten entsprechen, entsprechen Spalten verschiedene x-Werten --- wie inlist(list((x, y) for x in xs) for y in ys)
, der der folgende Array geben würde:Zweitens werden
meshgrid
die x- und y-Koordinaten getrennt zurückgegeben (dh in zwei verschiedenen numpy 2d-Arrays):Beachten Sie, dass
np.meshgrid
auch Gitter für höhere Dimensionen generiert werden können. Bei xs, ys und zs erhalten Sie xcoords, ycoords, zcoords als 3D-Arrays zurück.meshgrid
unterstützt auch die umgekehrte Reihenfolge der Dimensionen sowie die spärliche Darstellung des Ergebnisses.Anwendungen
Warum sollten wir diese Form der Ausgabe wollen?
Wenden Sie an jedem Punkt eines Rasters eine Funktion an: Eine Motivation ist, dass binäre Operatoren wie (+, -, *, /, **) für numpy-Arrays als elementweise Operationen überladen werden. Das heißt, wenn ich eine Funktion habe
def f(x, y): return (x - y) ** 2
, die auf zwei Skalaren funktioniert , kann ich sie auch auf zwei Numpy-Arrays anwenden, um ein Array mit elementweisen Ergebnissen zu erhalten: z. B.f(xcoords, ycoords)
oderf(*np.meshgrid(xs, ys))
gibt im obigen Beispiel Folgendes an:Höherdimensionales Außenprodukt: Ich bin mir nicht sicher, wie effizient dies ist, aber Sie können hochdimensionale Außenprodukte auf diese Weise erhalten :
np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)
.Konturdiagramme in matplotlib: Ich habe dies
meshgrid
bei der Untersuchung von Konturplots mit matplotlib Zeichnung für Grenzen Entscheidung Plotten . Dazu generieren Sie ein Raster mitmeshgrid
, werten die Funktion an jedem Rasterpunkt aus (z. B. wie oben gezeigt) und übergeben dann die x-, y- und berechneten f-Werte (dh zcoords) an die Konturfunktion.quelle