O objetivo de meshgrid
é criar uma grade retangular a partir de uma matriz de valores x e uma matriz de valores y.
Assim, por exemplo, se queremos criar uma grade em que temos um ponto em cada valor inteiro entre 0 e 4 nas direções x e y. Para criar uma grade retangular, precisamos de todas as combinações dos pontos x
e y
.
Serão 25 pontos, certo? Portanto, se desejássemos criar uma matriz xey para todos esses pontos, poderíamos fazer o seguinte.
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
Isso resultaria no seguinte x
e em y
matrizes, de modo que o emparelhamento do elemento correspondente em cada matriz forneça as coordenadas x e y de um ponto na grade.
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
Podemos então plotá-los para verificar se eles são uma grade:
plt.plot(x,y, marker='.', color='k', linestyle='none')
Obviamente, isso fica muito tedioso, especialmente para grandes faixas de x
e y
. Em vez disso, meshgrid
pode realmente gerar isso para nós: tudo o que precisamos especificar são os únicos x
e os y
valores.
xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);
Agora, quando ligamos meshgrid
, obtemos a saída anterior automaticamente.
xx, yy = np.meshgrid(xvalues, yvalues)
plt.plot(xx, yy, marker='.', color='k', linestyle='none')
A criação dessas grades retangulares é útil para várias tarefas. No exemplo que você forneceu em sua postagem, é simplesmente uma maneira de provar uma função ( sin(x**2 + y**2) / (x**2 + y**2)
) em um intervalo de valores para x
e y
.
Como essa função foi amostrada em uma grade retangular, a função agora pode ser visualizada como uma "imagem".
Além disso, o resultado agora pode ser passado para funções que esperam dados na grade retangular (ou seja contourf
)
xx
eyy
. A parte misteriosa para mim foi por que ele retorna esse par de resultados e como eles são. A resposta de Hai Phan é útil para isso. Eu acho que faz isso por conveniência, já que o enredo quer dois parâmetros assim.xx = [xvalues for y in yvalues]
yy = [[y for x in xvalues] for y in yvalues]
x
ey
para trás? Quando você o fazxx, yy = np.meshgrid(np.arange(4), np.arange(4))
, é o inverso do que você temx
ey
na primeira parte da resposta.mgrid
Corresponde à ordem das saídas para , mas não para o meshgrid. Elexx
deve estar aumentando na direção x, mas o seu aumenta na direção y.Cortesia do Microsoft Excel:
fonte
XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
np.vstack([XX.ravel(), YY.ravel()]).T
Na verdade, o objetivo de
np.meshgrid
já está mencionado na documentação:Portanto, seu principal objetivo é criar matrizes de coordenadas.
Você provavelmente só se perguntou:
Por que precisamos criar matrizes de coordenadas?
O motivo pelo qual você precisa de matrizes de coordenadas com Python / NumPy é que não há relação direta entre coordenadas e valores, exceto quando suas coordenadas começam com zero e são inteiros puramente positivos. Então você pode apenas usar os índices de uma matriz como o índice. No entanto, quando esse não for o caso, você precisará armazenar coordenadas de alguma forma com seus dados. É aí que as redes entram.
Suponha que seus dados sejam:
No entanto, cada valor representa uma região de 2 km de largura horizontalmente e 3 km de vertical. Suponha que sua origem seja o canto superior esquerdo e você deseje matrizes que representem a distância que você poderia usar:
onde v é:
e h:
Portanto, se você tiver dois índices, digamos
x
ey
(é por isso que o valor de retornomeshgrid
é geralmentexx
ou emxs
vez dex
, neste caso, eu escolhih
horizontalmente!), Então você pode obter a coordenada x do ponto, a coordenada y do ponto e a valor nesse ponto usando:Isso facilita muito o controle das coordenadas e (ainda mais importante) você pode transmiti-las para funções que precisam conhecer as coordenadas.
Uma explicação um pouco mais longa
No entanto,
np.meshgrid
ele próprio não costuma ser usado diretamente, principalmente se usa apenas objetos semelhantesnp.mgrid
ounp.ogrid
. Aquinp.mgrid
representa osparse=False
enp.ogrid
osparse=True
caso (refiro-me aosparse
argumento denp.meshgrid
). Observe que há uma diferença significativa entrenp.meshgrid
enp.ogrid
enp.mgrid
: Os dois primeiros valores retornados (se houver dois ou mais) são revertidos. Geralmente isso não importa, mas você deve fornecer nomes significativos de variáveis, dependendo do contexto.Por exemplo, no caso de uma grade 2D e
matplotlib.pyplot.imshow
faz sentido nomear o primeiro item retornadonp.meshgrid
x
e o segundoy
enquanto é o contrário denp.mgrid
enp.ogrid
.np.ogrid
e grades esparsasComo já foi dito, a saída é revertida quando comparada a
np.meshgrid
, é por isso que eu a descompactei como emyy, xx
vez dexx, yy
:Isso já parece coordenadas, especificamente as linhas x e y para plotagens 2D.
Visualizado:
np.mgrid
e grades densas / polidasO mesmo se aplica aqui: A saída é revertida em comparação com
np.meshgrid
:Diferentemente
ogrid
dessas matrizes, contém todas as coordenadasxx
eyy
-5 <= xx <= 5; -5 <= aa <= 5 grade.Funcionalidade
Não se limita apenas ao 2D, essas funções funcionam para dimensões arbitrárias (bem, há um número máximo de argumentos dados para funcionar no Python e um número máximo de dimensões que o NumPy permite):
Mesmo que isso também funcione para 1D, existem duas (muito mais comuns) funções de criação de grade 1D:
np.arange
np.linspace
Além do argumento
start
e,stop
ele também suporta ostep
argumento (mesmo etapas complexas que representam o número de etapas):Formulários
Você perguntou especificamente sobre o objetivo e, de fato, essas grades são extremamente úteis se você precisar de um sistema de coordenadas.
Por exemplo, se você tiver uma função NumPy que calcula a distância em duas dimensões:
E você quer saber a distância de cada ponto:
A saída seria idêntica se alguém passasse em uma grade densa em vez de uma grade aberta. A transmissão do NumPys torna isso possível!
Vamos visualizar o resultado:
E este é também quando NumPys
mgrid
eogrid
tornar-se muito conveniente, pois permite que você altere facilmente a resolução de suas grades:No entanto, como
imshow
não suportax
ey
insere, é necessário alterar os ticks manualmente. Seria realmente conveniente se ele aceitasse as coordenadasx
ey
, certo?É fácil escrever funções com o NumPy que lidam naturalmente com grades. Além disso, existem várias funções no NumPy, SciPy, matplotlib que esperam que você passe na grade.
Eu gosto de imagens, então vamos explorar
matplotlib.pyplot.contour
:Observe como as coordenadas já estão definidas corretamente! Esse não seria o caso se você apenas passasse no
density
.Ou, para dar outro exemplo divertido usando modelos de astropia (desta vez não me importo muito com as coordenadas, apenas as uso para criar uma grade):
Embora isso seja apenas "para a aparência", várias funções relacionadas a modelos funcionais e acessórios (por exemplo
scipy.interpolate.interp2d
,scipy.interpolate.griddata
até mostram exemplos usandonp.mgrid
) no Scipy etc. requerem grades. A maioria deles trabalha com grades abertas e grades densas, no entanto, algumas funcionam apenas com uma delas.fonte
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
- uma vez que são 2 km na horizontal e 3 km na vertical, o primeiro intervalo não deve ser multiplicado por 2 e o segundo por 3?Suponha que você tenha uma função:
e você deseja, por exemplo, ver como fica no intervalo de 0 a 2 * pi. Como você faria? Aí
np.meshgrid
entra:e esse enredo seria semelhante a:
Então,
np.meshgrid
é apenas uma conveniência. Em princípio, o mesmo poderia ser feito por:mas é preciso estar ciente de suas dimensões (suponha que você tenha mais de duas ...) e a transmissão correta.
np.meshgrid
faz tudo isso para você.Além disso, o meshgrid permite excluir coordenadas juntamente com os dados se, por exemplo, você desejar fazer uma interpolação, mas excluir determinados valores:
então, como você faria a interpolação agora? Você pode dar
x
ey
para uma função de interpolação comoscipy.interpolate.interp2d
então você precisa encontrar uma maneira de saber quais as coordenadas foram excluídos:e então você ainda pode interpolar com as coordenadas "corretas" (tente sem o meshgrid e você terá muito código extra):
e a malha original permite obter a interpolação na grade original novamente:
Estes são apenas alguns exemplos em que eu usei o
meshgrid
pode haver muito mais.fonte
xx
,yy
. Era difícil entender o que são e por que os usamos para calcular a função. Parece que eu entendi. Queremos calcular alguma função com base em coordenadas. Podemos escrever algo assim: emfor x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)
vez disso, calculamosz
de uma maneira diferentez=sin([x,x,...,x]) + sin([y,y,..y])
. Corrija-me se eu estiver errada!numpy
arquivá- lo com : malha ou transmissão. Se você não descarta pontos (veja a última parte da minha resposta), ambos são realmente funcionais equivalentes. A transmissão é apenas um loop implícito na dimensão a ser transmitida. Observe que eu usei[:,None]
e[None, :]
incluí dimensões extras para que o resultado seja transmitido corretamente. Seu segundo exemplo é mais como:sin([[y],[y],..[y]])
interpolated_grid = interpolated(xx, yy)
- isso não funciona para mim, erro:x and y should both be 1-D arrays
O meshgrid ajuda a criar uma grade retangular a partir de duas matrizes 1-D de todos os pares de pontos das duas matrizes.
Agora, se você definiu uma função f (x, y) e deseja aplicar essa função a toda a combinação possível de pontos das matrizes 'x' e 'y', pode fazer o seguinte:
Digamos, se sua função produz apenas o produto de dois elementos, é assim que um produto cartesiano pode ser alcançado, com eficiência, para grandes matrizes.
Referido a partir daqui
fonte
Ideia básica
Dados os possíveis valores de x
xs
, (pense neles como as marcas no eixo x de um gráfico) e os possíveis valores de yys
,meshgrid
gera o conjunto correspondente de pontos de grade (x, y) --- análogos aset((x, y) for x in xs for y in yx)
. Por exemplo, sexs=[1,2,3]
eys=[4,5,6]
, obteríamos o conjunto de coordenadas{(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}
.Forma do valor de retorno
No entanto, a representação que
meshgrid
retorna é diferente da expressão acima de duas maneiras:Primeiro ,
meshgrid
expõe os pontos da grade em uma matriz 2D: linhas correspondem a diferentes valores y, colunas correspondem a diferentes valores x --- como emlist(list((x, y) for x in xs) for y in ys)
, o que daria a seguinte matriz:Segundo ,
meshgrid
retorna as coordenadas x e y separadamente (ou seja, em duas matrizes 2d numpy diferentes):Observe
np.meshgrid
que também pode gerar grades para dimensões mais altas. Dados xs, ys e zs, você recuperaria xcoords, ycoords, zcoords como matrizes 3D.meshgrid
também suporta a ordem inversa das dimensões, bem como a representação esparsa do resultado.Formulários
Por que queremos essa forma de saída?
Aplique uma função em todos os pontos da grade: Uma motivação é que operadores binários como (+, -, *, /, **) sejam sobrecarregados para matrizes numpy como operações elementares. Isso significa que, se eu tiver uma função
def f(x, y): return (x - y) ** 2
que funcione em dois escalares, também posso aplicá-la em duas matrizes numpy para obter uma matriz de resultados elementares: por exemplo,f(xcoords, ycoords)
ouf(*np.meshgrid(xs, ys))
forneça o seguinte no exemplo acima:Superior produto externo dimensional: Eu não tenho certeza o quão eficiente este é, mas você pode obter produtos exteriores elevadas dimensões desta forma:
np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)
.Gráficos de contorno no matplotlib: deparei-me
meshgrid
ao investigar desenho de gráficos de contorno com matplotlib para plotar limites de decisão . Para isso, você gera uma grade commeshgrid
, avalia a função em cada ponto da grade (por exemplo, como mostrado acima) e depois passa os xcoords, ycoords e os valores f calculados (ou seja, zcoords) para a função de contorno.fonte