Python / NumPy'de meshgrid'in amacı nedir?


303

Birisi bana meshgridNumpy'deki fonksiyonun amacının ne olduğunu açıklayabilir mi? Çizim için bir tür koordinat ızgarası oluşturduğunu biliyorum, ama bunun doğrudan faydasını gerçekten göremiyorum.

Sebastian Raschka'dan "Python Machine Learning" okuyorum ve karar sınırlarını çizmek için kullanıyor. Buradaki giriş 11'e bakın .

Bu kodu resmi belgelerden de denedim, ancak yine, çıktı gerçekten benim için anlamlı değil.

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)

Lütfen, mümkünse, bana birçok gerçek dünya örneği de gösterin.

Yanıtlar:


391

Amacı, meshgridx değeri dizisinden ve y değerleri dizisinden dikdörtgen bir ızgara oluşturmaktır.

Örneğin, her bir tamsayı değerinde hem x hem de y yönlerinde 0 ile 4 arasında bir noktaya sahip olduğumuz bir ızgara oluşturmak istiyorsak. Dikdörtgen bir ızgara oluşturmak için xve ynoktalarının her kombinasyonuna ihtiyacımız var .

Bu 25 puan olacak, değil mi? Biz bu noktaların hepsi için bir x ve y diziyi oluşturmak isterse Demek ki olabilir aşağıdakileri yapın.

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

Bu , her bir matristeki karşılık gelen elemanın eşleştirilmesi, ızgaradaki bir noktanın x ve y koordinatlarını verecek şekilde aşağıdaki xve ymatrislerle sonuçlanır .

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

Daha sonra bunların bir ızgara olduklarını doğrulamak için bunları çizebiliriz:

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

resim açıklamasını buraya girin

Açıkçası, bu özellikle xve ve geniş aralıkları için çok sıkıcı olur y. Bunun yerine, meshgridbunu aslında bizim için üretebilir: belirtmemiz gereken tek şey benzersiz xve ydeğerlerdir.

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

Şimdi aradığımızda meshgrid, önceki çıktıyı otomatik olarak alıyoruz.

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

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

resim açıklamasını buraya girin

Bu dikdörtgen ızgaraların oluşturulması bir dizi görev için yararlıdır. Yayınınızda sağladığınız örnekte, yalnızca ve sin(x**2 + y**2) / (x**2 + y**2)için bir değer aralığı üzerinden bir işlevi ( ) örneklemenin bir yoludur .xy

Bu işlev dikdörtgen bir ızgarada örneklendiğinden, işlev artık bir "görüntü" olarak görüntülenebilir.

resim açıklamasını buraya girin

Ek olarak, sonuç şimdi dikdörtgen ızgara üzerinde veri bekleyen işlevlere aktarılabilir (örn. contourf)


10
Dönüş değerlerini açıklamadınız xxve yy. Benim için gizemli kısım, neden bu sonuç çiftini ve neye benzediklerini geri döndürmesiydi. Hai Phan'ın cevabı bunun için kullanışlıdır. Sanırım kolaylık sağlamak için bunu yapıyor, çünkü arsa böyle iki parametre istiyor.
nealmcb

2
Bilmiyorum - bu yüzden bu bilgiyi araştırıyorum;) Bu yüzden farklı bir şey döndürmesi gerektiğini söylemiyorum. Kabul ettiğim yanıtı okuyanlar için en iyi tahminin eksik bir bilgi parçasını sağlıyorum. Ve eğer isterseniz, geri dönüş değerlerini (Hai'nin yaptığı gibi) açıkladıysanız, hala şaşkın olanlarımız için cevabınızın (zaten çok güzel - teşekkürler!) Biraz daha eksiksiz olacağını öneriyorum.
nealmcb

1
Xx ve yy değerlerini daha iyi anlamak için, aşağıdaki kodun np.meshgrid ile aynı sonucu aldığını iddia edin:xx = [xvalues for y in yvalues] yy = [[y for x in xvalues] for y in yvalues]
Matt Kleinsmith

1
Bu cevap kafa karıştırıcı senin ilk illüstrasyon değil mi olduğunu xve ygeriye? Bunu yaptığınızda xx, yy = np.meshgrid(np.arange(4), np.arange(4)), size ne tersidir xve ycevabın birinci bölümünde. mgridMeshgrid için çıkışların sırası ile eşleşir , ancak kafesle eşleşmez. xxX-yönünde artan olmalıdır, ancak y yönünde sizin artar.
Scott Staniewicz

1
@ScottStaniewicz İşaret ettiğin için teşekkürler bizim, şimdi emin nasıl berbat bir ... Güncelleme!
Suever

250

Microsoft Excel'in izniyle: 

resim açıklamasını buraya girin


6
Güzel. Fwiw, ortada çiftlerin 2 x 12 dizisini istiyorsanız:XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
denis

5
ve ortada çiftlerin 12 x 2 dizi istiyorsanız:XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
barlaensdoonn

2
Güzel cevap. Meshgrid'in amacı, her bir loşun koordinatını kullanarak bir ızgara oluşturmaktır.
İyi çocuk

1
Biraz garip buldum, x ve y değerlerinin zaten bir dizi halinde birleştirilmesi yerine ayrı olarak döndürülmesidir. Onları bir dizide istiyorsam, yapmam gerekenler:np.vstack([XX.ravel(), YY.ravel()]).T
user3629892

66

Aslında np.meshgriddokümantasyonda amaç zaten belirtilmiştir:

np.meshgrid

Koordinat vektörlerinden koordinat matrislerini döndürür.

Tek boyutlu koordinat dizileri x1, x2, ..., xn verilen ND ızgaraları üzerinde ND skaler / vektör alanlarının vektörize değerlendirmeleri için ND koordinat dizileri yapın.

Yani asıl amacı bir koordinat matrisi oluşturmaktır.

Muhtemelen sadece kendinize sordunuz:

Neden koordinat matrisleri oluşturmamız gerekiyor?

Python / NumPy ile koordinat matrislerine ihtiyaç duymanızın nedeni, koordinatlarınızın sıfırla başlaması ve tamamen pozitif tamsayılar dışında, koordinatlardan değerlere doğrudan bir ilişkisinin olmamasıdır. Daha sonra bir dizinin dizinlerini dizin olarak kullanabilirsiniz. Ancak durum böyle olmadığında, verilerinizin yanında koordinatları bir şekilde depolamanız gerekir. Izgaralar burada devreye giriyor.

Verilerinizin:

1  2  1
2  5  2
1  2  1

Ancak, her bir değer yatay olarak 2 kilometre genişliğinde ve dikey olarak 3 kilometre genişliğindedir. Kökeninizin sol üst köşede olduğunu ve kullanabileceğiniz mesafeyi temsil eden diziler istediğinizi varsayalım:

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

burada v:

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

ve h:

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

İki endeks var ise, diyelim ki xve y(dönüş değeri neden en yani meshgridgenellikle xxya xsyerine xben seçtim bu durumda ho zaman x noktasının koordinatı alabilirsiniz yatay için!), Y noktası ve koordinatı bu noktadaki değeri kullanarak:

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

Bu, koordinatları takip etmeyi çok daha kolay hale getirir ve (daha da önemlisi) onları koordinatları bilmesi gereken işlevlere geçirebilirsiniz.

Biraz daha uzun bir açıklama

Ancak, np.meshgridkendisi genellikle doğrudan kullanılmaz, çoğunlukla biri sadece benzer nesnelerden birini kullanır np.mgridveya np.ogrid. Burada np.mgridtemsil sparse=Falseve dava (I atıfta argümanı ). Ve ile arasında önemli bir fark olduğunu unutmayın : Döndürülen ilk iki değer (iki veya daha fazla varsa) tersine çevrilir. Genellikle bu önemli değildir, ancak bağlama bağlı olarak anlamlı değişken adları vermelisiniz.np.ogridsparse=Truesparsenp.meshgridnp.meshgridnp.ogridnp.mgrid

Örneğin, bir 2B ızgara durumunda ve matplotlib.pyplot.imshowbunun ilk iade öğeyi isim mantıklı np.meshgrid xve ikincisini yne için tersi ise np.mgridve np.ogrid.

np.ogrid ve seyrek ızgaralar

>>> 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]])
       

Daha önce de belirtildiği gibi, çıktı ile karşılaştırıldığında tersine çevrildi np.meshgrid, bu yüzden yy, xxbunun yerine paketini açtım 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]])

Bu zaten koordinatlara benziyor, özellikle 2B grafikler için x ve y çizgileri.

görsel:

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")

resim açıklamasını buraya girin

np.mgrid ve yoğun / etli ızgaralar

>>> 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]])
       

Aynısı burada da geçerlidir: Çıktı aşağıdakilerle karşılaştırıldığında tersine çevrilir 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]])
       

ogridBu dizilerin aksine -5 <= xx <= 5 içindeki tüm xx ve yykoordinatları içerir ; -5 <= yy <= 5 ızgara.

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")

resim açıklamasını buraya girin

İşlevsellik

Sadece 2B ile sınırlı değildir, bu işlevler keyfi boyutlar için çalışır (Python'da işlev için maksimum sayıda argüman ve NumPy'nin izin verdiği maksimum boyut sayısı vardır):

>>> 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.

Bunlar 1D için de çalışsa bile iki (çok daha yaygın) 1D ızgara oluşturma işlevi vardır:

startVe stopargümanının yanı sıra argümanı da destekler step(adım sayısını temsil eden karmaşık adımlar bile):

>>> 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.]])
       

Uygulamalar

Özellikle amacı sordunuz ve aslında bir koordinat sistemine ihtiyacınız varsa bu ızgaralar son derece kullanışlıdır.

Örneğin, mesafeyi iki boyutta hesaplayan bir NumPy işleviniz varsa:

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

Ve her noktanın mesafesini bilmek istersiniz:

>>> 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]])
        

Biri açık bir ızgara yerine yoğun bir ızgaradan geçtiğinde çıktı aynı olacaktır. NumPys yayını mümkün kılar!

Sonucu görselleştirelim:

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()

resim açıklamasını buraya girin

Ve bu da NumPys olduğunda mgridve ogridçok uygun hale geldiğinde, çünkü ızgaralarınızın çözünürlüğünü kolayca değiştirmenize izin verir:

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

resim açıklamasını buraya girin

Ancak, imshowdesteklemediğinden xve ygirdiler desteklenmediğinden , kenelerin elle değiştirilmesi gerekir. xVe ykoordinatlarını kabul etmesi gerçekten uygun olurdu , değil mi?

Izgaralarla doğal olarak ilgilenen NumPy ile fonksiyon yazmak kolaydır. Ayrıca, NumPy, SciPy, matplotlib'de ızgaraya geçmenizi bekleyen çeşitli işlevler vardır.

Görüntüleri seviyorum, bu yüzden keşfedelim 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)

resim açıklamasını buraya girin

Koordinatların nasıl doğru ayarlandığına dikkat edin! Eğer daha yeni geçmiş olsaydın durum böyle olmazdı density.

Veya astropi modelleri kullanarak başka bir eğlenceli örnek vermek için (bu sefer koordinatlar hakkında pek umurumda değil, sadece bazı ızgaralar oluşturmak için kullanıyorum ):

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)
    

resim açıklamasını buraya girin

Bu sadece "görünümler için" olmasına rağmen, Scipy, vs.'deki fonksiyonel modeller ve fitting ile ilgili çeşitli işlevler (örneğin scipy.interpolate.interp2d, scipy.interpolate.griddataörnekleri kullanarak bile göster np.mgrid) ızgaralar gerektirir. Bunların çoğu açık ızgaralar ve yoğun ızgaralarla çalışır, ancak bazıları sadece bunlardan biriyle çalışır.


Bu son derece ayrıntılı cevap için çok teşekkür ederim. Bu benim günümü yaptı.
Jlanger

Bir soruyu cevaplamak için ne güzel bir yol .... çok ayrıntılı. Teşekkür ederim
Bipin

h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)- 2km yatay ve 3km dikey olduğundan, ilk menzil 2 ve ikincisi 3 ile çarpılmamalı mı?
Nixt

@Nixt Maalesef bu kadar basit değil. Cevabın bu kısmını tekrar kontrol etmem gerekebilir. Bu, matrisin transpoze edilmiş ekranı ile ters indeksleme arasında bir denge - normalde ilk indeksin yatay ve ikinci dikey olmasını beklersiniz, ancak ekran transpoze edilir. Bununla birlikte, bu çoğunlukla ızgaraların nedenini göstermeyi amaçlayan cevabın özünü geçersiz kılmayan bir detaydır. Ama bunu ileriki bir tarihte gözden geçirmeye çalışacağım.
MSeifert

36

Bir fonksiyonunuz olduğunu varsayalım:

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

örneğin, 0 ile 2 * pi aralığında neye benzediğini görmek istersiniz. Nasıl yapardın? İçeri np.meshgridgiriyor:

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

ve böyle bir arsa şöyle görünecektir:

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

resim açıklamasını buraya girin

Yani np.meshgridsadece bir kolaylık. Prensipte aynı şey şu şekilde yapılabilir:

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

ama orada boyutlarınızın (ikiden fazla var diyelim ...) ve doğru yayının farkında olmanız gerekir. np.meshgridtüm bunları sizin için yapar.

Ayrıca meshgrid, örneğin bir enterpolasyon yapmak, ancak belirli değerleri hariç tutmak istiyorsanız, verilerle birlikte koordinatları silmenizi sağlar:

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

peki şimdi enterpolasyonu nasıl yapardın? Sen verebilir xve yböyle bir interpolasyon işlevine scipy.interpolate.interp2dsildiğiniz hangi koordinatları bilmesi mümkün gerekir böylece:

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

ve sonra hala "doğru" koordinatlarla enterpolasyon yapabilirsiniz (meshgrid olmadan deneyin ve çok fazla ek kodunuz olacak):

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

ve orijinal meshgrid, enterpolasyonu orijinal ızgarada tekrar almanızı sağlar:

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

Bunlar benim kullandığım bazı örnekler meshgrid.


1
Cevabınız için teşekkür ederim! Benim için en kafa karıştırıcı an değerlerini döndürülür xx, yy. Ne olduklarını ve bunları işlevi hesaplamak için neden kullandığımızı anlamak zordu. Anlaşıldı, anladım. Bazı fonksiyonları koordinatlara göre hesaplamak istiyoruz. for x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)Bunun gibi bir şey yazabiliriz: Bunun yerine zfarklı bir şekilde hesaplıyoruz z=sin([x,x,...,x]) + sin([y,y,..y]). Eğer Yanlışsam beni düzelt!
Alena Kastsiukavets

% 100 doğru sahte kod değil, ama umarım benim
açımı görüyorsun

Aslında her zaman çift döngüye (ilk kodunuza) ihtiyacınız vardır. Ancak onu arşivlemenin farklı yolları vardır numpy: meshgrid veya yayın. Noktaları atmazsanız (cevabımın son bölümüne bakınız) her ikisi de aslında işlevsel olarak eşdeğerdir. Yayın, yayınlanacak boyutta örtülü bir döngüdür. Sonuçların doğru yayınlanması için kullandığım [:,None]ve [None, :]ekstra boyutlar eklediğimi unutmayın. İkinci örneğiniz daha çok:sin([[y],[y],..[y]])
MSeifert

Gerçekten güzel bir örnek. Çok çaba harcadığınız için teşekkürler.
natersoz

interpolated_grid = interpolated(xx, yy)- bu benim için işe yaramıyor, hata:x and y should both be 1-D arrays
Nixt

4

meshgrid, iki diziden tüm nokta çiftlerinin iki 1-D dizisinden dikdörtgen bir ızgara oluşturulmasına yardımcı olur.

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

Şimdi, f (x, y) işlevini tanımladıysanız ve bu işlevi 'x' ve 'y' dizilerinden olası tüm olası kombinasyonlara uygulamak istiyorsanız, bunu yapabilirsiniz:

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

Diyelim ki, fonksiyonunuz sadece iki elementin ürününü üretiyorsa, büyük diziler için etkili bir şekilde kartezyen bir ürün bu şekilde elde edilebilir.

Buradan başvurulan


1

Temel fikir

Verilen da x değerleri, xsve olası y değerleri (bir grafiğinin x-ekseni üzerinde kene işaretleri olarak bunların düşünün) ys, meshgridbenzer (x, y) ızgara noktaları --- karşılık gelen bir dizi oluşturur set((x, y) for x in xs for y in yx). Örneğin, eğer xs=[1,2,3]ve ys=[4,5,6], koordinatlar kümesini alırdık {(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}.

Dönüş Değerinin Şekli

Ancak, meshgridgeri dönen gösterim , yukarıdaki ifadeden iki şekilde farklıdır:

İlk olarak , meshgrid2d dizisindeki ızgara noktalarını düzenler: satırlar farklı y değerlerine karşılık gelir, sütunlar farklı x değerlerine karşılık gelir --- olduğu gibi list(list((x, y) for x in xs) for y in ys), aşağıdaki diziyi verir:

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

İkincisi , meshgridx ve y koordinatlarını ayrı ayrı döndürür (yani iki farklı numpy 2d dizisinde):

   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

Not np.meshgriddaha yüksek boyutlar için ızgaraları üretebilir. Xs, ys ve zs verildiğinde, 3d diziler olarak xcoords, ycoords, zcoordları geri alırsınız. meshgridayrıca boyutların ters sıralanmasını ve sonucun seyrek gösterimini destekler.

Uygulamalar

Neden bu çıktı biçimini istiyoruz?

Izgara üzerindeki her noktaya bir fonksiyon uygulayın: Bir motivasyon, (+, -, *, /, **) gibi ikili operatörlerin sayısal diziler için elemanlı işlemler olarak aşırı yüklenmesidir. Bu def f(x, y): return (x - y) ** 2, iki skaler üzerinde çalışan bir fonksiyonum varsa , bir dizi elemanlı sonuç almak için iki numpy dizisine de uygulayabileceğim anlamına gelir : örneğin f(xcoords, ycoords)veya f(*np.meshgrid(xs, ys))yukarıdaki örnekte aşağıdakileri verir:

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

Daha yüksek boyutlu dış ürün: Ben bu değil emin ne kadar verimli, ama yüksek boyutlu dış ürünler bu şekilde elde edebilirsiniz: np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0).

Matplotlib içinde Kontur araziler: Ben rastladım meshgridaraştırılırken matplotlib ile kontur araziler çizim için karar sınırlarını komplo . Bunun için meshgrid, her ızgara noktasındaki (örneğin yukarıda gösterildiği gibi) işlevi değerlendiren bir ızgara oluşturursunuz ve ardından xcoords, ycoords ve hesaplanan f-değerlerini (yani zcoords) konturf fonksiyonuna geçirirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.