Qual è lo scopo di meshgrid in Python / NumPy?


303

Qualcuno può spiegarmi qual è lo scopo della meshgridfunzione in Numpy? So che crea una sorta di griglia di coordinate per la stampa, ma non riesco davvero a vederne il beneficio diretto.

Sto studiando "Python Machine Learning" di Sebastian Raschka, e lo sta usando per tracciare i confini delle decisioni. Vedi input 11 qui .

Ho anche provato questo codice dalla documentazione ufficiale, ma, di nuovo, l'output non ha davvero senso per me.

x = np.arange(-5, 5, 1)
y = np.arange(-5, 5, 1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x,y,z)

Per favore, se possibile, mostrami anche molti esempi del mondo reale.

Risposte:


391

Lo scopo di meshgridè quello di creare una griglia rettangolare da una matrice di valori x e una matrice di valori y.

Ad esempio, se vogliamo creare una griglia in cui abbiamo un punto per ogni valore intero compreso tra 0 e 4 nelle direzioni xe y. Per creare una griglia rettangolare, abbiamo bisogno di ogni combinazione dei punti xe y.

Saranno 25 punti, giusto? Quindi, se abbiamo voluto creare una x e y serie per tutti questi punti, abbiamo potuto effettuare le seguenti operazioni.

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

Ciò comporterebbe le seguenti xe le ymatrici, in modo tale che l'accoppiamento dell'elemento corrispondente in ciascuna matrice fornisca le coordinate xey di un punto nella griglia.

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

Possiamo quindi tracciarli per verificare che siano una griglia:

plt.plot(x,y, marker='.', color='k', linestyle='none')

inserisci qui la descrizione dell'immagine

Ovviamente, questo diventa molto noioso soprattutto per le grandi gamme di xe y. Invece, in meshgridrealtà possiamo generarlo per noi: tutto ciò che dobbiamo specificare sono unici xe yvalori.

xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);

Ora, quando chiamiamo meshgrid, otteniamo automaticamente l'output precedente.

xx, yy = np.meshgrid(xvalues, yvalues)

plt.plot(xx, yy, marker='.', color='k', linestyle='none')

inserisci qui la descrizione dell'immagine

La creazione di queste griglie rettangolari è utile per una serie di attività. Nell'esempio che hai fornito nel tuo post, è semplicemente un modo per campionare una funzione ( sin(x**2 + y**2) / (x**2 + y**2)) su un intervallo di valori per xe y.

Poiché questa funzione è stata campionata su una griglia rettangolare, la funzione può ora essere visualizzata come "immagine".

inserisci qui la descrizione dell'immagine

Inoltre, il risultato può ora essere passato a funzioni che prevedono dati su griglia rettangolare (es. contourf)


10
Non hai spiegato i valori di ritorno xxe yy. La parte misteriosa per me è stata la ragione per cui restituisce quella coppia di risultati e che aspetto hanno. La risposta di Hai Phan è utile per questo. Immagino che lo faccia per comodità, poiché la trama vuole due parametri del genere.
nealmcb,

2
Non lo so - ecco perché sto cercando queste informazioni;) Quindi non sto dicendo che dovrebbe restituire qualcosa di diverso. Sto solo fornendo la mia migliore ipotesi a un pezzo mancante di informazioni per coloro che hanno appena letto la risposta accettata. E se ti piace, sto suggerendo che la tua risposta (che è già molto carina - grazie!) Sarebbe un po 'più completa se spiegassi i valori di ritorno (come ha fatto Hai), per quelli di noi che sono ancora perplessi.
nealmcb,

1
Per comprendere meglio i valori di xx e yy, considera l'affermazione che il seguente codice ti dà lo stesso risultato di np.meshgrid:xx = [xvalues for y in yvalues] yy = [[y for x in xvalues] for y in yvalues]
Matt Kleinsmith,

1
Questa risposta è confusa: non è la tua prima illustrazione di xe al contrario y? Quando lo fai xx, yy = np.meshgrid(np.arange(4), np.arange(4)), è il contrario di ciò che hai xe ynella prima parte della risposta. mgridCorrisponde all'ordine degli output per , ma non meshgrid. Il xxdovrebbe aumentare nella direzione x, ma la tua aumenti nella direzione y.
Scott Staniewicz,

1
@ScottStaniewicz Grazie per averlo indicato, ora sono sicuro di come ho rovinato quello ... Aggiornato!
Suever,

249

Per gentile concessione di Microsoft Excel: 

inserisci qui la descrizione dell'immagine


6
Bello. Dopo, se vuoi una matrice 2 x 12 delle coppie nel mezzo:XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
denis

5
e se vuoi una matrice 12 x 2 delle coppie nel mezzo:XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
barlaensdoonn,

2
Bella risposta. Lo scopo di meshgrid è di creare una griglia usando le coordinate di ciascun dim.
Bravo ragazzo,

1
Quello che trovo un po 'strano è che i valori xey vengono restituiti separatamente anziché già combinati in un array. Se li voglio in un array, devo fare:np.vstack([XX.ravel(), YY.ravel()]).T
user3629892 il

66

In realtà lo scopo di np.meshgridè già menzionato nella documentazione:

np.meshgrid

Restituisce le matrici di coordinate dai vettori di coordinate.

Crea array di coordinate ND per valutazioni vettoriali di campi scalari / vettoriali ND su griglie ND, dati gli array di coordinate unidimensionali x1, x2, ..., xn.

Quindi il suo scopo principale è quello di creare una matrice di coordinate.

Probabilmente ti sei appena chiesto:

Perché è necessario creare matrici di coordinate?

La ragione per cui hai bisogno di matrici di coordinate con Python / NumPy è che non esiste una relazione diretta tra coordinate e valori, tranne quando le tue coordinate iniziano con zero e sono numeri puramente positivi. Quindi puoi semplicemente usare gli indici di un array come indice. Tuttavia, in caso contrario, è necessario in qualche modo memorizzare le coordinate accanto ai dati. Ecco dove arrivano le griglie.

Supponiamo che i tuoi dati siano:

1  2  1
2  5  2
1  2  1

Tuttavia, ogni valore rappresenta una regione larga 2 chilometri in orizzontale e 3 chilometri in verticale. Supponiamo che la tua origine sia l'angolo in alto a sinistra e desideri array che rappresentino la distanza che potresti usare:

import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)

dove v è:

array([[0, 0, 0],
       [2, 2, 2],
       [4, 4, 4]])

e h:

array([[0, 3, 6],
       [0, 3, 6],
       [0, 3, 6]])

Quindi, se hai due indici, diciamo xe y(ecco perché il valore di ritorno meshgridè di solito xxo xsinvece che xin questo caso ho scelto horizzontalmente!) Allora puoi ottenere la coordinata x del punto, la coordinata y del punto e il valore a quel punto usando:

h[x, y]    # horizontal coordinate
v[x, y]    # vertical coordinate
data[x, y]  # value

Ciò rende molto più semplice tenere traccia delle coordinate e (ancora più importante) è possibile passarle a funzioni che devono conoscere le coordinate.

Una spiegazione leggermente più lunga

Tuttavia, di per np.meshgridsé non viene spesso utilizzato direttamente, per lo più si utilizza solo uno di oggetti similinp.mgrid o np.ogrid. Qui np.mgridrappresenta il sparse=Falsee np.ogridil sparse=Truecaso (mi riferisco alla sparsetesi di np.meshgrid). Si noti che esiste una differenza significativa tra np.meshgride np.ogride np.mgrid: i primi due valori restituiti (se ce ne sono due o più) vengono invertiti. Spesso questo non ha importanza, ma è necessario assegnare nomi di variabili significativi a seconda del contesto.

Ad esempio, nel caso di una griglia 2D e matplotlib.pyplot.imshowha senso nominare il primo elemento restituito np.meshgrid xe il secondo ymentre è il contrario per np.mgride np.ogrid.

np.ogrid e griglie sparse

>>> import numpy as np
>>> yy, xx = np.ogrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5],
       [-4],
       [-3],
       [-2],
       [-1],
       [ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5]])
       

Come già detto, l'output è invertito rispetto a np.meshgrid, ecco perché l'ho decompresso yy, xxinvece di xx, yy:

>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6), sparse=True)
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5],
       [-4],
       [-3],
       [-2],
       [-1],
       [ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5]])

Sembra già coordinate, in particolare le linee xey per i grafici 2D.

visualizzati:

yy, xx = np.ogrid[-5:6, -5:6]
plt.figure()
plt.title('ogrid (sparse meshgrid)')
plt.grid()
plt.xticks(xx.ravel())
plt.yticks(yy.ravel())
plt.scatter(xx, np.zeros_like(xx), color="blue", marker="*")
plt.scatter(np.zeros_like(yy), yy, color="red", marker="x")

inserisci qui la descrizione dell'immagine

np.mgrid e griglie dense / rafforzate

>>> yy, xx = np.mgrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4],
       [ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]])
       

Lo stesso vale qui: l'output è invertito rispetto a np.meshgrid:

>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6))
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4],
       [ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]])
       

A differenza di ogridquesti array contengono tutto xx e le yycoordinate in -5 <= xx <= 5; -5 <= aa <= 5 griglia.

yy, xx = np.mgrid[-5:6, -5:6]
plt.figure()
plt.title('mgrid (dense meshgrid)')
plt.grid()
plt.xticks(xx[0])
plt.yticks(yy[:, 0])
plt.scatter(xx, yy, color="red", marker="x")

inserisci qui la descrizione dell'immagine

Funzionalità

Non è limitato solo al 2D, queste funzioni funzionano per dimensioni arbitrarie (beh, c'è un numero massimo di argomenti dati per funzionare in Python e un numero massimo di dimensioni consentite da NumPy):

>>> x1, x2, x3, x4 = np.ogrid[:3, 1:4, 2:5, 3:6]
>>> for i, x in enumerate([x1, x2, x3, x4]):
...     print('x{}'.format(i+1))
...     print(repr(x))
x1
array([[[[0]]],


       [[[1]]],


       [[[2]]]])
x2
array([[[[1]],

        [[2]],

        [[3]]]])
x3
array([[[[2],
         [3],
         [4]]]])
x4
array([[[[3, 4, 5]]]])

>>> # equivalent meshgrid output, note how the first two arguments are reversed and the unpacking
>>> x2, x1, x3, x4 = np.meshgrid(np.arange(1,4), np.arange(3), np.arange(2, 5), np.arange(3, 6), sparse=True)
>>> for i, x in enumerate([x1, x2, x3, x4]):
...     print('x{}'.format(i+1))
...     print(repr(x))
# Identical output so it's omitted here.

Anche se funzionano anche per 1D, ci sono due (molto più comuni) funzioni di creazione della griglia 1D:

Oltre all'argomento starte stopsupporta anche l' stepargomento (anche passaggi complessi che rappresentano il numero di passaggi):

>>> x1, x2 = np.mgrid[1:10:2, 1:10:4j]
>>> x1  # The dimension with the explicit step width of 2
array([[1., 1., 1., 1.],
       [3., 3., 3., 3.],
       [5., 5., 5., 5.],
       [7., 7., 7., 7.],
       [9., 9., 9., 9.]])
>>> x2  # The dimension with the "number of steps"
array([[ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.]])
       

applicazioni

Hai specificamente chiesto lo scopo e, infatti, queste griglie sono estremamente utili se hai bisogno di un sistema di coordinate.

Ad esempio se si dispone di una funzione NumPy che calcola la distanza in due dimensioni:

def distance_2d(x_point, y_point, x, y):
    return np.hypot(x-x_point, y-y_point)
    

E vuoi sapere la distanza di ogni punto:

>>> ys, xs = np.ogrid[-5:5, -5:5]
>>> distances = distance_2d(1, 2, xs, ys)  # distance to point (1, 2)
>>> distances
array([[9.21954446, 8.60232527, 8.06225775, 7.61577311, 7.28010989,
        7.07106781, 7.        , 7.07106781, 7.28010989, 7.61577311],
       [8.48528137, 7.81024968, 7.21110255, 6.70820393, 6.32455532,
        6.08276253, 6.        , 6.08276253, 6.32455532, 6.70820393],
       [7.81024968, 7.07106781, 6.40312424, 5.83095189, 5.38516481,
        5.09901951, 5.        , 5.09901951, 5.38516481, 5.83095189],
       [7.21110255, 6.40312424, 5.65685425, 5.        , 4.47213595,
        4.12310563, 4.        , 4.12310563, 4.47213595, 5.        ],
       [6.70820393, 5.83095189, 5.        , 4.24264069, 3.60555128,
        3.16227766, 3.        , 3.16227766, 3.60555128, 4.24264069],
       [6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
        2.23606798, 2.        , 2.23606798, 2.82842712, 3.60555128],
       [6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
        1.41421356, 1.        , 1.41421356, 2.23606798, 3.16227766],
       [6.        , 5.        , 4.        , 3.        , 2.        ,
        1.        , 0.        , 1.        , 2.        , 3.        ],
       [6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
        1.41421356, 1.        , 1.41421356, 2.23606798, 3.16227766],
       [6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
        2.23606798, 2.        , 2.23606798, 2.82842712, 3.60555128]])
        

L'output sarebbe identico se si passasse in una griglia densa anziché in una griglia aperta. La trasmissione NumPys lo rende possibile!

Visualizziamo il risultato:

plt.figure()
plt.title('distance to point (1, 2)')
plt.imshow(distances, origin='lower', interpolation="none")
plt.xticks(np.arange(xs.shape[1]), xs.ravel())  # need to set the ticks manually
plt.yticks(np.arange(ys.shape[0]), ys.ravel())
plt.colorbar()

inserisci qui la descrizione dell'immagine

E questo è anche quando NumPys mgride ogriddiventa molto conveniente perché ti consente di cambiare facilmente la risoluzione delle tue griglie:

ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above

inserisci qui la descrizione dell'immagine

Tuttavia, poiché imshownon supporta xe yinput, è necessario modificare manualmente i tick. Sarebbe davvero conveniente se accettasse le coordinate xe y, giusto?

È facile scrivere funzioni con NumPy che gestiscono naturalmente le griglie. Inoltre, ci sono diverse funzioni in NumPy, SciPy, matplotlib che prevedono di passare nella griglia.

Mi piacciono le immagini, quindi esploriamo matplotlib.pyplot.contour:

ys, xs = np.mgrid[-5:5:200j, -5:5:200j]
density = np.sin(ys)-np.cos(xs)
plt.figure()
plt.contour(xs, ys, density)

inserisci qui la descrizione dell'immagine

Nota come le coordinate sono già impostate correttamente! Non sarebbe il caso se si fosse appena passati in density.

O per fare un altro esempio divertente usando i modelli di astropia (questa volta non mi interessa molto le coordinate, le uso semplicemente per creare una griglia):

from astropy.modeling import models
z = np.zeros((100, 100))
y, x = np.mgrid[0:100, 0:100]
for _ in range(10):
    g2d = models.Gaussian2D(amplitude=100, 
                           x_mean=np.random.randint(0, 100), 
                           y_mean=np.random.randint(0, 100), 
                           x_stddev=3, 
                           y_stddev=3)
    z += g2d(x, y)
    a2d = models.AiryDisk2D(amplitude=70, 
                            x_0=np.random.randint(0, 100), 
                            y_0=np.random.randint(0, 100), 
                            radius=5)
    z += a2d(x, y)
    

inserisci qui la descrizione dell'immagine

Anche se questo è solo "per gli sguardi", diverse funzioni relative ai modelli funzionali e all'adattamento (ad esempio scipy.interpolate.interp2d, scipy.interpolate.griddatamostrano anche gli esempi che utilizzano np.mgrid) in Scipy, ecc. Richiedono delle griglie. La maggior parte di questi funziona con griglie aperte e griglie dense, tuttavia alcune funzionano solo con una di esse.


Voglio solo dire un enorme grazie per questa risposta estremamente dettagliata. Mi ha cambiato la giornata in positivo.
Jlanger,

Che bel modo di rispondere a una domanda .... così dettagliata. Grazie
Bipin il

h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)- poiché i suoi 2 km in orizzontale e 3 km in verticale, la prima distanza non dovrebbe essere moltiplicata per 2 e la seconda per 3?
Nixt,

@Nixt Purtroppo non è così semplice. Potrei dover ricontrollare quella parte della risposta. È un compromesso tra la visualizzazione trasposta della matrice e l'indicizzazione inversa - normalmente ci si aspetta che il primo indice sia orizzontale e il secondo verticale, ma poi il display venga trasposto. Tuttavia, questo è principalmente un dettaglio che si spera non invalidi l'essenza della risposta che mira a illustrare il motivo delle griglie. Ma proverò a rivederlo in una data futura.
MSeifert,

36

Supponiamo di avere una funzione:

def sinus2d(x, y):
    return np.sin(x) + np.sin(y)

e vuoi, ad esempio, vedere come appare nell'intervallo da 0 a 2 * pi. Come lo faresti? Ci np.meshgridviene in:

xx, yy = np.meshgrid(np.linspace(0,2*np.pi,100), np.linspace(0,2*np.pi,100))
z = sinus2d(xx, yy) # Create the image on this grid

e tale trama sarebbe simile a:

import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', interpolation='none')
plt.show()

inserisci qui la descrizione dell'immagine

Quindi np.meshgridè solo una comodità. In linea di principio lo stesso potrebbe essere fatto mediante:

z2 = sinus2d(np.linspace(0,2*np.pi,100)[:,None], np.linspace(0,2*np.pi,100)[None,:])

ma lì devi essere consapevole delle tue dimensioni (supponi di avere più di due ...) e la giusta trasmissione. np.meshgridfa tutto questo per te.

Inoltre meshgrid consente di eliminare le coordinate insieme ai dati se, ad esempio, si desidera eseguire un'interpolazione ma escludere determinati valori:

condition = z>0.6
z_new = z[condition] # This will make your array 1D

quindi come faresti l'interpolazione ora? Si può dare xe yad una funzione di interpolazione come scipy.interpolate.interp2dquindi è necessario un modo per sapere che le coordinate sono stati cancellati:

x_new = xx[condition]
y_new = yy[condition]

e poi puoi ancora interpolare con le coordinate "giuste" (provalo senza meshgrid e avrai un sacco di codice extra):

from scipy.interpolate import interp2d
interpolated = interp2d(x_new, y_new, z_new)

e la meshgrid originale consente di ottenere nuovamente l'interpolazione sulla griglia originale:

interpolated_grid = interpolated(xx[0], yy[:, 0]).reshape(xx.shape)

Questi sono solo alcuni esempi in cui ho usato meshgridci potrebbe essere molto di più.


1
La ringrazio per la risposta! Il momento più confusione per me viene restituito valori xx, yy. È stato difficile capire cosa sono e perché li usiamo per calcolare la funzione. Sembra che ho capito. Vogliamo calcolare alcune funzioni in base alle coordinate. Possiamo scrivere qualcosa del genere: for x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)calcoliamo invece zin modo diverso z=sin([x,x,...,x]) + sin([y,y,..y]). Correggimi se sbaglio!
Alena Kastsiukavets,

Non è uno pseudo codice corretto al 100%, ma spero che tu
capisca il

In realtà hai sempre bisogno del doppio loop (il tuo primo codice). Ma ci sono diversi modi per archiviarlo numpy: meshgrid o broadcasting. Se non scarti punti (vedi l'ultima parte della mia risposta) entrambi sono effettivamente funzionalmente equivalenti. La trasmissione è solo un ciclo implicito attraverso la dimensione da trasmettere. Nota che ho usato [:,None]e [None, :]per includere dimensioni extra in modo che il risultato venga trasmesso correttamente. Il tuo secondo esempio è più simile a:sin([[y],[y],..[y]])
MSeifert

Un'illustrazione davvero bella. Grazie per aver dedicato così tanto impegno.
natersoz,

interpolated_grid = interpolated(xx, yy)- questo non funziona per me, errore:x and y should both be 1-D arrays
Nixt

4

meshgrid aiuta a creare una griglia rettangolare da due array 1-D di tutte le coppie di punti dai due array.

x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 1, 2, 3, 4])

Ora, se hai definito una funzione f (x, y) e vuoi applicare questa funzione a tutte le possibili combinazioni di punti dalle matrici 'x' e 'y', allora puoi farlo:

f(*np.meshgrid(x, y))

Ad esempio, se la tua funzione produce solo il prodotto di due elementi, allora è così che un prodotto cartesiano può essere raggiunto, in modo efficiente per array di grandi dimensioni.

Riferito da qui


1

Idea base

Dati possibili valori x xs, (pensali come i segni di spunta sull'asse x di un grafico) e possibili valori y ys, meshgridgenera il corrispondente set di punti della griglia (x, y) --- analogo a set((x, y) for x in xs for y in yx). Ad esempio, se xs=[1,2,3]e ys=[4,5,6], otterremmo l'insieme di coordinate {(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}.

Forma del valore di ritorno

Tuttavia, la rappresentazione che meshgridrestituisce è diversa dall'espressione precedente in due modi:

Innanzitutto , meshgridstabilisce i punti della griglia in un array 2d: le righe corrispondono a diversi valori y, le colonne corrispondono a diversi valori x --- come in list(list((x, y) for x in xs) for y in ys), che darebbe il seguente array:

   [[(1,4), (2,4), (3,4)],
    [(1,5), (2,5), (3,5)],
    [(1,6), (2,6), (3,6)]]

In secondo luogo , meshgridrestituisce le coordinate xey separatamente (ovvero in due diverse matrici numpy 2d):

   xcoords, ycoords = (
       array([[1, 2, 3],
              [1, 2, 3],
              [1, 2, 3]]),
       array([[4, 4, 4],
              [5, 5, 5],
              [6, 6, 6]]))
   # same thing using np.meshgrid:
   xcoords, ycoords = np.meshgrid([1,2,3], [4,5,6])
   # same thing without meshgrid:
   xcoords = np.array([xs] * len(ys)
   ycoords = np.array([ys] * len(xs)).T

Nota, np.meshgridpuò anche generare griglie per dimensioni superiori. Dati xs, ys e zs, si otterrebbero xcoords, ycoords, zcoords come array 3d. meshgridsupporta anche l'ordinamento inverso delle dimensioni e la rappresentazione sparsa del risultato.

applicazioni

Perché dovremmo desiderare questa forma di output?

Applicare una funzione in ogni punto di una griglia: una motivazione è che gli operatori binari come (+, -, *, /, **) sono sovraccaricati per le matrici intorpidite come operazioni elementally. Ciò significa che se ho una funzione def f(x, y): return (x - y) ** 2che funziona su due scalari, posso anche applicarla su due array intorpiditi per ottenere una matrice di risultati elementwise: ad esempio f(xcoords, ycoords)o f(*np.meshgrid(xs, ys))fornisce quanto segue nell'esempio sopra:

array([[ 9,  4,  1],
       [16,  9,  4],
       [25, 16,  9]])

Prodotto esterno dimensionale superiore: Non sono sicuro di quanto sia efficiente questo è, ma è possibile ottenere prodotti esterni di alta-dimensionale in questo modo: np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0).

Grafici di contorno in matplotlib: mi sono imbattutomeshgrid nell'ambito delle indagini disegnare grafici di contorno con matplotlib per tracciare i confini di decisione . Per questo, si genera una griglia con meshgrid, si valuta la funzione in ciascun punto della griglia (ad es. Come mostrato sopra), quindi si passano i xcoords, ycoords e i valori f calcolati (cioè zcoords) nella funzione contourf.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.