El propósito de meshgrid
es crear una cuadrícula rectangular a partir de una matriz de valores xy una matriz de valores y.
Entonces, por ejemplo, si queremos crear una cuadrícula donde tengamos un punto en cada valor entero entre 0 y 4 en las direcciones x e y. Para crear una cuadrícula rectangular, necesitamos todas las combinaciones de los puntos x
y y
.
Esto va a ser 25 puntos, ¿verdad? Entonces, si quisiéramos crear una matriz x e y para todos estos puntos, podríamos hacer lo siguiente.
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
Esto daría como resultado las siguientes x
y y
matrices, de modo que el emparejamiento del elemento correspondiente en cada matriz da las coordenadas x e y de un punto en la cuadrícula.
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
Luego podemos trazar estos para verificar que son una cuadrícula:
plt.plot(x,y, marker='.', color='k', linestyle='none')
Obviamente, esto se vuelve muy tedioso, especialmente para grandes rangos de x
y y
. En cambio, en meshgrid
realidad puede generar esto para nosotros: todo lo que tenemos que especificar son los valores únicos x
y únicos y
.
xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);
Ahora, cuando llamamos meshgrid
, obtenemos la salida anterior automáticamente.
xx, yy = np.meshgrid(xvalues, yvalues)
plt.plot(xx, yy, marker='.', color='k', linestyle='none')
La creación de estas cuadrículas rectangulares es útil para una serie de tareas. En el ejemplo que ha proporcionado en su publicación, es simplemente una forma de muestrear una función ( sin(x**2 + y**2) / (x**2 + y**2)
) en un rango de valores para x
y y
.
Debido a que esta función se ha muestreado en una cuadrícula rectangular, la función ahora se puede visualizar como una "imagen".
Además, el resultado ahora se puede pasar a funciones que esperan datos en una cuadrícula rectangular (es decir contourf
)
xx
yyy
. La parte misteriosa para mí fue por qué devuelve ese par de resultados y cómo se ven. La respuesta de Hai Phan es útil para eso. Supongo que lo hace por conveniencia, ya que plot quiere dos parámetros como ese.xx = [xvalues for y in yvalues]
yy = [[y for x in xvalues] for y in yvalues]
x
yy
hacia atrás? Cuando lo hacesxx, yy = np.meshgrid(np.arange(4), np.arange(4))
, es lo contrario de lo que tienesx
yy
en la primera parte de la respuesta.mgrid
Coincide con el orden de las salidas para , pero no meshgrid. Elxx
debería estar aumentando en la dirección x, pero el tuyo aumenta en la dirección y.Cortesía de Microsoft Excel:
fuente
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 realidad, el propósito de
np.meshgrid
ya se menciona en la documentación:Por lo tanto, su objetivo principal es crear matrices de coordenadas.
Probablemente te hayas preguntado a ti mismo:
¿Por qué necesitamos crear matrices de coordenadas?
La razón por la que necesita matrices de coordenadas con Python / NumPy es que no hay una relación directa de coordenadas a valores, excepto cuando sus coordenadas comienzan con cero y son enteros puramente positivos. Entonces puede usar los índices de una matriz como índice. Sin embargo, cuando ese no es el caso, de alguna manera necesita almacenar coordenadas junto con sus datos. Ahí es donde entran las cuadrículas.
Supongamos que sus datos son:
Sin embargo, cada valor representa una región de 2 kilómetros de ancho horizontalmente y 3 kilómetros verticalmente. Suponga que su origen es la esquina superior izquierda y desea matrices que representen la distancia que podría usar:
donde v es:
y h:
Entonces, si tiene dos índices, digamos
x
yy
(es por eso que el valor de retorno demeshgrid
usualmentexx
o enxs
lugar dex
en este caso elijoh
horizontalmente), entonces puede obtener la coordenada x del punto, la coordenada y del punto y el valor en ese punto usando:Eso hace que sea mucho más fácil hacer un seguimiento de las coordenadas y (aún más importante) puede pasarlas a funciones que necesitan conocer las coordenadas.
Una explicación un poco más larga.
Sin embargo,
np.meshgrid
a menudo no se usa directamente, en su mayoría solo se usa uno de objetos similaresnp.mgrid
onp.ogrid
. Aquínp.mgrid
representa elsparse=False
ynp.ogrid
elsparse=True
caso (me refiero alsparse
argumento delnp.meshgrid
). Tenga en cuenta que hay una diferencia significativa entrenp.meshgrid
ynp.ogrid
ynp.mgrid
: Los dos primeros valores devueltos (si hay dos o más) se invierten. A menudo, esto no importa, pero debe dar nombres de variables significativos según el contexto.Por ejemplo, en el caso de una cuadrícula 2D y
matplotlib.pyplot.imshow
tiene sentido nombrar el primer elemento devuelto denp.meshgrid
x
y el segundoy
mientras es al revés paranp.mgrid
ynp.ogrid
.np.ogrid
y rejillas dispersasComo ya se dijo, la salida se invierte en comparación con
np.meshgrid
, por eso lo desempaqué como enyy, xx
lugar dexx, yy
:Esto ya parece coordenadas, específicamente las líneas x e y para gráficos 2D.
Visualizado:
np.mgrid
y rejillas densas / desarrolladasLo mismo se aplica aquí: la salida se invierte en comparación con
np.meshgrid
:A diferencia de
ogrid
estas matrices contienen todasxx
yyy
coordenadas en -5 <= xx <= 5; -5 <= aa <= 5 cuadrícula.Funcionalidad
No solo se limita a 2D, estas funciones funcionan para dimensiones arbitrarias (bueno, hay un número máximo de argumentos dados para funcionar en Python y un número máximo de dimensiones que NumPy permite):
Incluso si estos también funcionan para 1D, hay dos funciones de creación de cuadrícula 1D (mucho más comunes):
np.arange
np.linspace
Además del argumento
start
ystop
, también admite elstep
argumento (incluso pasos complejos que representan el número de pasos):Aplicaciones
Usted preguntó específicamente sobre el propósito y, de hecho, estas cuadrículas son extremadamente útiles si necesita un sistema de coordenadas.
Por ejemplo, si tiene una función NumPy que calcula la distancia en dos dimensiones:
Y quieres saber la distancia de cada punto:
La salida sería idéntica si se pasara en una grilla densa en lugar de una grilla abierta. ¡La transmisión de NumPys lo hace posible!
Visualicemos el resultado:
Y esto también es cuando NumPys
mgrid
y seogrid
vuelve muy conveniente porque le permite cambiar fácilmente la resolución de sus cuadrículas:Sin embargo, dado
imshow
que no admitex
ey
ingresa, uno tiene que cambiar los ticks a mano. Sería realmente conveniente si aceptara elx
yy
coordenadas , ¿verdad?Es fácil escribir funciones con NumPy que tratan naturalmente con cuadrículas. Además, hay varias funciones en NumPy, SciPy, matplotlib que esperan que pase en la cuadrícula.
Me gustan las imágenes, así que exploremos
matplotlib.pyplot.contour
:¡Observe cómo las coordenadas ya están configuradas correctamente! Ese no sería el caso si acabaras de pasar
density
.O para dar otro ejemplo divertido usando modelos de astropía (esta vez no me importan mucho las coordenadas, solo las uso para crear una cuadrícula):
Aunque eso es solo "por el aspecto", varias funciones relacionadas con modelos funcionales y ajuste (por ejemplo
scipy.interpolate.interp2d
,scipy.interpolate.griddata
incluso mostrar ejemplos usandonp.mgrid
) en Scipy, etc. requieren cuadrículas. La mayoría de estos funcionan con rejillas abiertas y rejillas densas, sin embargo, algunos solo funcionan con uno de ellos.fuente
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
- Dado que sus 2 km horizontales y 3 km verticales, ¿no debería multiplicarse el primer rango por 2 y el segundo por 3?Supongamos que tiene una función:
y desea, por ejemplo, ver cómo se ve en el rango de 0 a 2 * pi. ¿Como lo harias? No
np.meshgrid
viene en:y esa trama se vería así:
Entonces
np.meshgrid
es solo una conveniencia. En principio, lo mismo podría hacerse:pero allí debe conocer sus dimensiones (suponga que tiene más de dos ...) y la transmisión correcta.
np.meshgrid
hace todo esto por ti.También meshgrid le permite eliminar coordenadas junto con los datos si, por ejemplo, desea hacer una interpolación pero excluye ciertos valores:
Entonces, ¿cómo harías la interpolación ahora? Usted puede dar
x
yy
de una función de interpolación comoscipy.interpolate.interp2d
por lo que necesita una manera de saber qué coordenadas se han eliminado:y aún puede interpolar con las coordenadas "correctas" (pruébelo sin la malla y tendrá mucho código extra):
y el meshgrid original le permite obtener la interpolación en el grid original nuevamente:
Estos son solo algunos ejemplos en los que usé el
meshgrid
que podría haber mucho más.fuente
xx
,yy
. Fue difícil entender qué son y por qué los usamos para calcular la función. Parece que lo tengo. Queremos calcular alguna función basada en coordenadas. Podemos escribir algo como esto: en sufor x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)
lugar, calculamosz
de una manera diferentez=sin([x,x,...,x]) + sin([y,y,..y])
. ¡Corrígeme si estoy equivocado!numpy
: meshgrid o broadcasting. Si no descarta puntos (vea la última parte de mi respuesta), ambos son funcionalmente equivalentes. La radiodifusión es solo un bucle implícito en la dimensión a ser transmitida. Tenga en cuenta que he utilizado[:,None]
y[None, :]
que incluyo dimensiones extra por lo que el resultado transmite correctamente. Su segundo ejemplo es más como:sin([[y],[y],..[y]])
interpolated_grid = interpolated(xx, yy)
- esto no funciona para mí, error:x and y should both be 1-D arrays
meshgrid ayuda a crear una cuadrícula rectangular a partir de dos matrices 1-D de todos los pares de puntos de las dos matrices.
Ahora, si ha definido una función f (x, y) y desea aplicar esta función a todas las combinaciones posibles de puntos de las matrices 'x' e 'y', puede hacer esto:
Digamos, si su función solo produce el producto de dos elementos, entonces así es como se puede lograr un producto cartesiano, de manera eficiente para grandes matrices.
Referido desde aquí
fuente
Idea básica
Dados los posibles valores de x
xs
, (piense en ellos como las marcas de graduación en el eje x de un gráfico) y los posibles valores de yys
,meshgrid
genera el conjunto correspondiente de puntos de cuadrícula (x, y) --- análogos aset((x, y) for x in xs for y in yx)
. Por ejemplo, sixs=[1,2,3]
yys=[4,5,6]
, obtendríamos el conjunto de coordenadas{(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}
.Forma del valor de retorno
Sin embargo, la representación que
meshgrid
devuelve es diferente de la expresión anterior de dos maneras:Primero ,
meshgrid
establece los puntos de la cuadrícula en una matriz 2d: las filas corresponden a diferentes valores de y, las columnas corresponden a diferentes valores de x --- como enlist(list((x, y) for x in xs) for y in ys)
, lo que daría la siguiente matriz:En segundo lugar ,
meshgrid
devuelve las coordenadas x e y por separado (es decir, en dos matrices 2d numpy diferentes):Tenga en cuenta
np.meshgrid
que también puede generar cuadrículas para dimensiones superiores. Dados xs, ys y zs, obtendría xcoords, ycoords, zcoords como matrices 3d.meshgrid
también admite el orden inverso de las dimensiones, así como una representación dispersa del resultado.Aplicaciones
¿Por qué querríamos esta forma de salida?
Aplique una función en cada punto de una cuadrícula: una motivación es que los operadores binarios como (+, -, *, /, **) están sobrecargados para matrices numpy como operaciones de elementos. Esto significa que si tengo una función
def f(x, y): return (x - y) ** 2
que funciona en dos escalares, también puedo aplicarla en dos matrices numpy para obtener una matriz de resultados por elementos: por ejemplo,f(xcoords, ycoords)
of(*np.meshgrid(xs, ys))
da lo siguiente en el ejemplo anterior:Producto externo de dimensiones superiores: No estoy seguro de qué tan eficiente es esto, pero usted puede conseguir productos de alta dimensión exterior de esta manera:
np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)
.Gráficos de contorno en matplotlib: Me encontré
meshgrid
al investigar el trazado de gráficos de contorno con matplotlib para trazar límites de decisión . Para esto, genera una cuadrícula conmeshgrid
, evalúa la función en cada punto de la cuadrícula (por ejemplo, como se muestra arriba) y luego pasa los xcoords, ycoords y los valores f calculados (es decir, zcoords) en la función contourf.fuente