Le but de meshgrid
est de créer une grille rectangulaire à partir d'un tableau de valeurs x et d'un tableau de valeurs y.
Ainsi, par exemple, si nous voulons créer une grille où nous avons un point à chaque valeur entière entre 0 et 4 dans les directions x et y. Pour créer une grille rectangulaire, nous avons besoin de chaque combinaison des points x
et y
.
Cela va être de 25 points, non? Donc, si nous voulions créer un tableau x et y pour tous ces points, nous pourrions faire ce qui suit.
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
Il en résulterait ce qui suit x
et des y
matrices, de sorte que l'appariement de l'élément correspondant dans chaque matrice donne les coordonnées x et y d'un point dans la grille.
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
Nous pouvons ensuite tracer ceux-ci pour vérifier qu'ils sont une grille:
plt.plot(x,y, marker='.', color='k', linestyle='none')
Évidemment, cela devient très fastidieux, en particulier pour les grandes gammes de x
et y
. Au lieu de cela, meshgrid
peut effectivement générer ce pour nous: tout ce que nous devons préciser sont les uniques x
et les y
valeurs.
xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);
Maintenant, lorsque nous appelons meshgrid
, nous obtenons automatiquement la sortie précédente.
xx, yy = np.meshgrid(xvalues, yvalues)
plt.plot(xx, yy, marker='.', color='k', linestyle='none')
La création de ces grilles rectangulaires est utile pour un certain nombre de tâches. Dans l'exemple que vous avez fourni dans votre article, c'est simplement un moyen d'échantillonner une fonction ( sin(x**2 + y**2) / (x**2 + y**2)
) sur une plage de valeurs pour x
et y
.
Parce que cette fonction a été échantillonnée sur une grille rectangulaire, la fonction peut maintenant être visualisée comme une "image".
De plus, le résultat peut maintenant être transmis aux fonctions qui attendent des données sur une grille rectangulaire (c.-à-d. contourf
)
xx
etyy
. La partie mystérieuse pour moi était pourquoi elle renvoie cette paire de résultats, et à quoi ils ressemblent. La réponse de Hai Phan est pratique pour cela. Je suppose que cela fait cela pour plus de commodité, car l'intrigue veut deux paramètres comme ça.xx = [xvalues for y in yvalues]
yy = [[y for x in xvalues] for y in yvalues]
x
et eny
arrière? Lorsque vous le faitesxx, yy = np.meshgrid(np.arange(4), np.arange(4))
, c'est l'inverse de ce que vous avezx
ety
dans la première partie de la réponse. Il correspond à l'ordre des sorties pourmgrid
, mais pas au meshgrid. Lexx
devrait augmenter dans la direction x, mais le vôtre augmente dans la direction y.Gracieuseté de Microsoft Excel:
la source
XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
np.vstack([XX.ravel(), YY.ravel()]).T
En fait, le but de
np.meshgrid
est déjà mentionné dans la documentation:Son objectif principal est donc de créer une matrice de coordonnées.
Vous vous êtes probablement demandé:
Pourquoi devons-nous créer des matrices de coordonnées?
La raison pour laquelle vous avez besoin de matrices de coordonnées avec Python / NumPy est qu'il n'y a pas de relation directe entre les coordonnées et les valeurs, sauf lorsque vos coordonnées commencent par zéro et sont des entiers purement positifs. Ensuite, vous pouvez simplement utiliser les indices d'un tableau comme index. Cependant, lorsque ce n'est pas le cas, vous devez en quelque sorte stocker les coordonnées à côté de vos données. C'est là qu'interviennent les grilles.
Supposons que vos données soient:
Cependant, chaque valeur représente une région de 2 kilomètres de large horizontalement et de 3 kilomètres verticalement. Supposons que votre origine soit le coin supérieur gauche et que vous vouliez des tableaux qui représentent la distance que vous pourriez utiliser:
où v est:
et h:
Donc, si vous avez deux indices, disons
x
ety
(c'est pourquoi la valeur de retour demeshgrid
est généralementxx
ouxs
au lieu dex
dans ce cas j'ai choisih
horizontalement!), Alors vous pouvez obtenir la coordonnée x du point, la coordonnée y du point et le valeur à ce point en utilisant:Cela facilite grandement le suivi des coordonnées et (plus important encore) vous pouvez les transmettre à des fonctions qui ont besoin de connaître les coordonnées.
Une explication un peu plus longue
Cependant,
np.meshgrid
lui-même n'est pas souvent utilisé directement, la plupart du temps, on utilise simplement l'un des objets similairesnp.mgrid
ounp.ogrid
. Icinp.mgrid
représente lesparse=False
etnp.ogrid
lesparse=True
cas (je me réfère à l'sparse
argument denp.meshgrid
). Notez qu'il existe une différence significative entrenp.meshgrid
etnp.ogrid
etnp.mgrid
: Les deux premières valeurs renvoyées (s'il y en a deux ou plus) sont inversées. Souvent, cela n'a pas d'importance, mais vous devez donner des noms de variables significatifs en fonction du contexte.Par exemple, dans le cas d'une grille 2D et
matplotlib.pyplot.imshow
il est logique de nommer le premier élément retourné denp.meshgrid
x
et le secondy
alors que c'est l'inverse pournp.mgrid
etnp.ogrid
.np.ogrid
et grilles clairseméesComme déjà dit, la sortie est inversée par rapport à
np.meshgrid
, c'est pourquoi je l'ai décompressée auyy, xx
lieu dexx, yy
:Cela ressemble déjà à des coordonnées, en particulier les lignes x et y pour les tracés 2D.
Visualisé:
np.mgrid
et grilles denses / étofféesIl en va de même ici: la sortie est inversée par rapport à
np.meshgrid
:Contrairement à
ogrid
ces tableaux contiennent tousxx
etyy
coordonnées dans le -5 <= xx <= 5; -5 <= yy <= 5 grille.Fonctionnalité
Ce n'est pas seulement limité à la 2D, ces fonctions fonctionnent pour des dimensions arbitraires (enfin, il y a un nombre maximum d'arguments donnés pour fonctionner en Python et un nombre maximum de dimensions que NumPy permet):
Même si ceux-ci fonctionnent également pour 1D, il existe deux fonctions de création de grille 1D (beaucoup plus courantes):
np.arange
np.linspace
Outre l' argument
start
etstop
, il prend également en charge l'step
argument (même les étapes complexes qui représentent le nombre d'étapes):Applications
Vous avez spécifiquement demandé à propos de l'objectif et en fait, ces grilles sont extrêmement utiles si vous avez besoin d'un système de coordonnées.
Par exemple, si vous avez une fonction NumPy qui calcule la distance en deux dimensions:
Et vous voulez connaître la distance de chaque point:
La sortie serait identique si l'on passait dans une grille dense au lieu d'une grille ouverte. La diffusion NumPys rend cela possible!
Visualisons le résultat:
Et cela est aussi quand NumPys
mgrid
etogrid
deviennent très pratique car il vous permet de changer facilement la résolution de vos grilles:Toutefois, étant donné que
imshow
ne prend pas en chargex
et lesy
entrées on doit changer les tiques à la main. Ce serait vraiment pratique s'il acceptait les coordonnéesx
ety
, n'est-ce pas?Il est facile d'écrire des fonctions avec NumPy qui traitent naturellement des grilles. De plus, il existe plusieurs fonctions dans NumPy, SciPy, matplotlib qui s'attendent à ce que vous passiez dans la grille.
J'aime les images alors explorons
matplotlib.pyplot.contour
:Notez comment les coordonnées sont déjà correctement définies! Ce ne serait pas le cas si vous veniez de passer le
density
.Ou pour donner un autre exemple amusant en utilisant des modèles d'astropie (cette fois, je ne me soucie pas beaucoup des coordonnées, je les utilise juste pour créer une grille):
Bien que ce soit juste "pour l'apparence", plusieurs fonctions liées aux modèles fonctionnels et à l'ajustement (par exemple
scipy.interpolate.interp2d
,scipy.interpolate.griddata
même montrer des exemples d'utilisationnp.mgrid
) dans Scipy, etc. nécessitent des grilles. La plupart d'entre eux fonctionnent avec des grilles ouvertes et des grilles denses, mais certains ne fonctionnent qu'avec l'une d'entre elles.la source
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
- depuis ses 2 km horizontaux et 3 km verticaux, la première plage ne doit-elle pas être multipliée par 2 et la seconde par 3?Supposons que vous ayez une fonction:
et vous voulez, par exemple, voir à quoi il ressemble dans la plage de 0 à 2 * pi. Comment feriez-vous? Il y a
np.meshgrid
:et un tel complot ressemblerait à:
C'est donc
np.meshgrid
juste une commodité. En principe, la même chose pourrait être faite par:mais là, vous devez être conscient de vos dimensions (supposons que vous en ayez plus de deux ...) et de la bonne diffusion.
np.meshgrid
fait tout cela pour vous.Le meshgrid vous permet également de supprimer les coordonnées avec les données si vous voulez, par exemple, faire une interpolation mais exclure certaines valeurs:
alors comment feriez-vous l'interpolation maintenant? Vous pouvez donner
x
ety
à une fonction d'interpolation commescipy.interpolate.interp2d
vous avez donc besoin d'un moyen de savoir quelles coordonnées ont été supprimées:et ensuite vous pouvez toujours interpoler avec les "bonnes" coordonnées (essayez-le sans le meshgrid et vous aurez beaucoup de code supplémentaire):
et le maillage d'origine vous permet d'obtenir à nouveau l'interpolation sur la grille d'origine:
Ce ne sont que quelques exemples où j'ai utilisé le
meshgrid
il pourrait y en avoir beaucoup plus.la source
xx
,yy
. Il était difficile de comprendre ce qu'ils sont et pourquoi nous les utilisons pour calculer la fonction. On dirait que je l'ai. Nous voulons calculer une fonction basée sur des coordonnées. Nous pouvons écrire quelque chose comme ceci:for x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)
Au lieu de cela, nous calculonsz
d'une manière différentez=sin([x,x,...,x]) + sin([y,y,..y])
. Corrigez-moi si je me trompe!numpy
: maillage ou diffusion. Si vous ne jetez pas de points (voir la dernière partie de ma réponse), les deux sont en fait fonctionnellement équivalents. La diffusion n'est qu'une boucle implicite à travers la dimension à diffuser. Notez que j'ai utilisé[:,None]
et[None, :]
pour inclure des dimensions supplémentaires afin que le résultat diffuse correctement. Votre deuxième exemple ressemble plus à:sin([[y],[y],..[y]])
interpolated_grid = interpolated(xx, yy)
- cela ne fonctionne pas pour moi, erreur:x and y should both be 1-D arrays
meshgrid aide à créer une grille rectangulaire à partir de deux tableaux 1-D de toutes les paires de points des deux tableaux.
Maintenant, si vous avez défini une fonction f (x, y) et que vous voulez appliquer cette fonction à toutes les combinaisons possibles de points des tableaux 'x' et 'y', alors vous pouvez le faire:
Disons que si votre fonction produit simplement le produit de deux éléments, c'est ainsi qu'un produit cartésien peut être réalisé, efficacement pour les grands tableaux.
Référé d' ici
la source
Idée basique
Compte tenu des valeurs possibles de x,
xs
, (les considérer comme les graduations sur l'axe des x d'une parcelle) et les valeurs y possibles,ys
,meshgrid
génère des points de grille ensemble de (x, y) correspondant --- analogues àset((x, y) for x in xs for y in yx)
. Par exemple, sixs=[1,2,3]
etys=[4,5,6]
, nous obtiendrions l'ensemble des coordonnées{(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}
.Forme de la valeur de retour
Cependant, la représentation
meshgrid
renvoyée diffère de l'expression ci-dessus de deux manières:Tout d'abord ,
meshgrid
établit les points de la grille dans un tableau 2d: les lignes correspondent à différentes valeurs y, les colonnes correspondent à différentes valeurs x --- comme danslist(list((x, y) for x in xs) for y in ys)
, ce qui donnerait le tableau suivant:Deuxièmement ,
meshgrid
renvoie les coordonnées x et y séparément (c'est-à-dire dans deux tableaux numpy 2d différents):Remarque,
np.meshgrid
peut également générer des grilles pour des dimensions supérieures. Étant donné xs, ys et zs, vous récupérez les xcoords, ycoords, zcoords sous forme de tableaux 3D.meshgrid
prend également en charge l'ordre inverse des dimensions ainsi qu'une représentation clairsemée du résultat.Applications
Pourquoi voudrions-nous cette forme de sortie?
Appliquer une fonction à chaque point d'une grille: Une motivation est que les opérateurs binaires comme (+, -, *, /, **) sont surchargés pour les tableaux numpy en tant qu'opérations élément par élément. Cela signifie que si j'ai une fonction
def f(x, y): return (x - y) ** 2
qui fonctionne sur deux scalaires, je peux également l'appliquer sur deux tableaux numpy pour obtenir un tableau de résultats élément par élément: par exemplef(xcoords, ycoords)
ouf(*np.meshgrid(xs, ys))
donne ce qui suit dans l'exemple ci-dessus:Produit extérieur supérieur dimensions: Je ne sais pas comment cela est efficace, mais vous pouvez obtenir des produits extérieurs de grande dimension ainsi:
np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)
.Tracés de contour dans matplotlib: Je suis tombé sur une
meshgrid
recherche de tracés de contour avec matplotlib pour tracer les limites de décision . Pour cela, vous générez une grille avecmeshgrid
, évaluez la fonction à chaque point de grille (par exemple, comme indiqué ci-dessus), puis passez les xcoords, ycoords et les valeurs f calculées (c'est-à-dire zcoords) dans la fonction contourf.la source