Sebenarnya tujuan np.meshgrid
sudah disebutkan dalam dokumentasi:
np.meshgrid
Kembalikan matriks koordinat dari vektor koordinat.
Buat susunan koordinat ND untuk evaluasi vektor bidang skalar / vektor ND di atas kisi ND, berikan susunan koordinat satu dimensi x1, x2, ..., xn.
Jadi tujuan utamanya adalah untuk membuat matriks koordinat.
Anda mungkin bertanya pada diri sendiri:
Mengapa kita perlu membuat matriks koordinat?
Alasan Anda memerlukan koordinat matriks dengan Python / NumPy adalah bahwa tidak ada hubungan langsung dari koordinat ke nilai, kecuali ketika koordinat Anda mulai dengan nol dan bilangan bulat murni positif. Kemudian Anda bisa menggunakan indeks array sebagai indeks. Namun ketika itu tidak terjadi, Anda harus menyimpan koordinat di samping data Anda. Di situlah grid masuk.
Misalkan data Anda adalah:
1 2 1
2 5 2
1 2 1
Namun, setiap nilai mewakili wilayah lebar 2 kilometer secara horizontal dan 3 kilometer secara vertikal. Misalkan asal Anda adalah sudut kiri atas dan Anda ingin array yang mewakili jarak yang dapat Anda gunakan:
import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
dimana v adalah:
array([[0, 0, 0],
[2, 2, 2],
[4, 4, 4]])
dan H:
array([[0, 3, 6],
[0, 3, 6],
[0, 3, 6]])
Jadi jika Anda memiliki dua indeks, katakanlah x
dan y
(itu sebabnya nilai balik meshgrid
biasanya xx
atau xs
bukan x
dalam kasus ini saya pilih h
secara horizontal!) Maka Anda bisa mendapatkan koordinat x titik, koordinat y titik dan nilai pada titik itu dengan menggunakan:
h[x, y] # horizontal coordinate
v[x, y] # vertical coordinate
data[x, y] # value
Itu membuatnya jauh lebih mudah untuk melacak koordinat dan (bahkan lebih penting) Anda dapat meneruskannya ke fungsi yang perlu mengetahui koordinat.
Penjelasan yang sedikit lebih panjang
Namun, np.meshgrid
itu sendiri tidak sering digunakan secara langsung, sebagian besar hanya menggunakan salah satu objek yang serupanp.mgrid
atau np.ogrid
. Berikut np.mgrid
merupakan sparse=False
dan np.ogrid
para sparse=True
kasus (saya merujuk pada sparse
argumen np.meshgrid
). Perhatikan bahwa ada perbedaan yang signifikan antara
np.meshgrid
dan np.ogrid
dan np.mgrid
: Dua nilai pertama yang dikembalikan (jika ada dua atau lebih) dibalik. Seringkali ini tidak masalah tetapi Anda harus memberikan nama variabel yang bermakna tergantung pada konteksnya.
Sebagai contoh, dalam kasus grid 2D dan matplotlib.pyplot.imshow
masuk akal untuk memberi nama item yang dikembalikan pertama np.meshgrid
x
dan yang kedua y
sementara itu sebaliknya untuk np.mgrid
dan np.ogrid
.
np.ogrid
dan grid yang jarang
>>> 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]])
Seperti yang sudah dikatakan, outputnya terbalik jika dibandingkan dengan np.meshgrid
, itu sebabnya saya membukanya sebagai yy, xx
ganti 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]])
Ini sudah terlihat seperti koordinat, khususnya garis x dan y untuk plot 2D.
Divisualisasikan:
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")
np.mgrid
dan grid padat / disempurnakan
>>> 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]])
Hal yang sama berlaku di sini: Output dibalik dibandingkan dengan 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]])
Berbeda dengan ogrid
array ini mengandung semua xx
dan yy
koordinat di -5 <= xx <= 5; -5 <= yy <= 5 kisi.
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")
Kegunaan
Ini tidak hanya terbatas pada 2D, fungsi-fungsi ini berfungsi untuk dimensi arbitrer (well, ada jumlah maksimum argumen yang diberikan untuk berfungsi dalam Python dan jumlah maksimum dimensi yang memungkinkan NumPy memungkinkan):
>>> 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.
Bahkan jika ini juga bekerja untuk 1D ada dua (1 lebih banyak) fungsi pembuatan grid 1D:
Selain start
dan stop
argumen itu juga mendukung step
argumen (bahkan langkah-langkah rumit yang mewakili jumlah langkah):
>>> 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.]])
Aplikasi
Anda secara khusus bertanya tentang tujuan dan pada kenyataannya, kisi-kisi ini sangat berguna jika Anda memerlukan sistem koordinat.
Misalnya jika Anda memiliki fungsi NumPy yang menghitung jarak dalam dua dimensi:
def distance_2d(x_point, y_point, x, y):
return np.hypot(x-x_point, y-y_point)
Dan Anda ingin tahu jarak setiap titik:
>>> 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]])
Outputnya akan sama jika seseorang lewat di grid padat bukannya grid terbuka. Penyiaran NumPys memungkinkan!
Mari kita visualisasikan hasilnya:
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()
Dan ini juga saat NumPys mgrid
dan ogrid
menjadi sangat nyaman karena memungkinkan Anda untuk dengan mudah mengubah resolusi grid Anda:
ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above
Namun, karena imshow
tidak mendukung x
dan y
input, Anda harus mengubah kutu dengan tangan. Akan sangat nyaman jika akan menerima x
dany
mengoordinasikan, kan?
Sangat mudah untuk menulis fungsi dengan NumPy yang secara alami berurusan dengan kisi. Selain itu, ada beberapa fungsi di NumPy, SciPy, matplotlib yang mengharapkan Anda untuk lulus dalam grid.
Saya suka gambar jadi mari kita jelajahi 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)
Perhatikan bagaimana koordinat sudah diatur dengan benar! Itu tidak akan terjadi jika Anda baru saja lewat di density
.
Atau untuk memberikan contoh lain yang menyenangkan menggunakan model astropi (kali ini saya tidak terlalu peduli dengan koordinat, saya hanya menggunakannya untuk membuat beberapa kotak):
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)
Meskipun itu hanya "untuk penampilan" beberapa fungsi yang berkaitan dengan model fungsional dan pemasangan (misalnya scipy.interpolate.interp2d
,
scipy.interpolate.griddata
bahkan menunjukkan contoh menggunakan np.mgrid
) dalam Scipy, dll memerlukan grid. Sebagian besar bekerja dengan grid terbuka dan grid padat, namun beberapa hanya bekerja dengan salah satunya.
xx
danyy
. Bagian misterius bagi saya adalah mengapa mengembalikan hasil, dan seperti apa hasilnya. Jawaban Hai Phan berguna untuk itu. Saya kira itu melakukan itu untuk kenyamanan, karena plot ingin dua parameter seperti itu.