वास्तव में इसका उद्देश्य np.meshgrid
पहले से ही प्रलेखन में उल्लिखित है:
np.meshgrid
समन्वय वैक्टर से रिटर्न समन्वय मैट्रिसेस।
एनडी स्केलर / वेक्टर क्षेत्रों के एनडी ग्रिडों के वेक्टरकृत मूल्यांकन के लिए एनडी समन्वय सारणी बनाएं, एक आयामी समन्वय एरे, एक्स 2, ..., एक्सएन को देखते हुए।
तो यह प्राथमिक उद्देश्य एक निर्देशांक matrices बनाने के लिए है।
आपने शायद खुद से पूछा:
हमें समन्वय मेट्रिसेस बनाने की आवश्यकता क्यों है?
पायथन / न्यूमपी के साथ समन्वित मैट्रिसेस की आवश्यकता का कारण यह है कि निर्देशांक से मूल्यों तक कोई सीधा संबंध नहीं है, सिवाय इसके कि जब आपके निर्देशांक शून्य से शुरू होते हैं और विशुद्ध रूप से सकारात्मक पूर्णांक होते हैं। फिर आप केवल इंडेक्स के रूप में एक सरणी के सूचकांकों का उपयोग कर सकते हैं। हालांकि जब ऐसा नहीं होता है तो आपको अपने डेटा के साथ-साथ निर्देशांक को संग्रहीत करने की आवश्यकता होती है। यहीं से ग्रिड आते हैं।
मान लीजिए कि आपका डेटा है:
1 2 1
2 5 2
1 2 1
हालाँकि, प्रत्येक मान 2 किलोमीटर चौड़े क्षेत्र को क्षैतिज रूप से और 3 किलोमीटर लंबवत रूप से दर्शाता है। मान लीजिए कि आपका मूल ऊपरी बाएँ कोने में है और आप ऐसी सरणियाँ चाहते हैं जो आपके द्वारा उपयोग की जा सकने वाली दूरी का प्रतिनिधित्व करें:
import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
वी कहाँ है:
array([[0, 0, 0],
[2, 2, 2],
[4, 4, 4]])
और वह:
array([[0, 3, 6],
[0, 3, 6],
[0, 3, 6]])
इसलिए यदि आपके पास दो सूचकांक हैं, तो आइए कहते हैं x
और y
(इसीलिए कि वापसी का मूल्य meshgrid
आमतौर पर है xx
या xs
इसके बजाय x
इस मामले में मैंने h
क्षैतिज रूप से चुना है!) तो आप बिंदु के x निर्देशांक, बिंदु के y निर्देशांक प्राप्त कर सकते हैं! उस बिंदु पर मूल्य का उपयोग करके:
h[x, y] # horizontal coordinate
v[x, y] # vertical coordinate
data[x, y] # value
यह निर्देशांक का ट्रैक रखने के लिए बहुत आसान बनाता है और (इससे भी महत्वपूर्ण बात) आप उन्हें उन कार्यों के लिए पारित कर सकते हैं जिन्हें निर्देशांक जानने की आवश्यकता है।
थोड़ा लंबा स्पष्टीकरण
हालांकि, np.meshgrid
खुद को अक्सर सीधे इस्तेमाल नहीं किया जाता है, ज्यादातर एक समान वस्तुओं का उपयोग करता है np.mgrid
या np.ogrid
। यहाँ np.mgrid
का प्रतिनिधित्व करता है sparse=False
और मामले (मैं का उल्लेख का तर्क )। ध्यान दें कि और : के बीच एक महत्वपूर्ण अंतर है
और पहले दो लौटे मान (यदि दो या अधिक हैं) उलट हैं। अक्सर यह मायने नहीं रखता है, लेकिन आपको संदर्भ के आधार पर सार्थक चर नाम देना चाहिए।np.ogrid
sparse=True
sparse
np.meshgrid
np.meshgrid
np.ogrid
np.mgrid
उदाहरण के लिए, एक 2 डी ग्रिड के मामले में और matplotlib.pyplot.imshow
यह समझ में आता है के पहले लौटे आइटम नाम के लिए np.meshgrid
x
और दूसरा एक y
, जबकि इसके लिए दूसरी तरह के आसपास है np.mgrid
और np.ogrid
।
>>> 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]])
जैसा कि पहले ही कहा जा सकता है np.meshgrid
कि जब इसकी तुलना में आउटपुट उल्टा हो जाता है , इसीलिए मैंने इसे yy, xx
इसके बजाय अनपैक कर दिया है 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]])
यह पहले से ही निर्देशांक की तरह दिखता है, विशेष रूप से 2 डी भूखंडों के लिए x और y लाइनें।
कल्पना:
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
और घने / मांस से बाहर ग्रिड
>>> 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]])
यहां भी यही बात लागू होती है: आउटपुट की तुलना में उल्टा होता है 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]])
ogrid
इन सरणियों के विपरीत सभी होते हैंxx
और yy
-5 <= xx <= 5 में निर्देशांक होते हैं ; -5 <= yy <= 5 ग्रिड।
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")
कार्यक्षमता
यह केवल 2 डी तक सीमित नहीं है, ये कार्य मनमाने आयामों के लिए काम करते हैं (ठीक है, पायथन में कार्य करने के लिए दिए गए तर्कों की अधिकतम संख्या है और अधिकतम संख्या में आयाम जो कि 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.
अगर ये 1 डी के लिए भी काम करते हैं तो भी दो (बहुत अधिक सामान्य) 1 डी ग्रिड निर्माण कार्य हैं:
तर्क start
और stop
तर्क के अलावा यह तर्क का समर्थन भी करता step
है (यहां तक कि जटिल कदम जो चरणों की संख्या का प्रतिनिधित्व करते हैं):
>>> 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.]])
अनुप्रयोग
आपने विशेष रूप से उद्देश्य के बारे में पूछा है और वास्तव में, ये ग्रिड अत्यंत उपयोगी हैं यदि आपको एक समन्वय प्रणाली की आवश्यकता है।
उदाहरण के लिए यदि आपके पास एक NumPy फ़ंक्शन है जो दो आयामों में दूरी की गणना करता है:
def distance_2d(x_point, y_point, x, y):
return np.hypot(x-x_point, y-y_point)
और आप प्रत्येक बिंदु की दूरी जानना चाहते हैं:
>>> 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]])
आउटपुट एक समान होगा यदि कोई खुली ग्रिड के बजाय एक घने ग्रिड में पारित हो गया। NumPys प्रसारण संभव बनाता है!
आइए परिणाम की कल्पना करें:
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()
और यह तब भी है जब NumPys mgrid
और ogrid
बहुत सुविधाजनक हो जाते हैं क्योंकि यह आपको आसानी से अपने ग्रिड के रिज़ॉल्यूशन को बदलने की अनुमति देता है:
ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above
हालाँकि, चूंकि imshow
कोई समर्थन x
और y
इनपुट नहीं करता है , इसलिए टिक को हाथ से बदलना होगा। यह वास्तव में सुविधाजनक होगा अगर यह स्वीकार करेगा x
और y
निर्देशांक करेगा, है ना?
NumPy के साथ फ़ंक्शन लिखना आसान है जो स्वाभाविक रूप से ग्रिड से निपटते हैं। इसके अलावा, NumPy, SciPy, matplotlib में कई कार्य हैं जो आपसे ग्रिड में पास होने की उम्मीद करते हैं।
मुझे चित्र पसंद हैं तो आइए देखें 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)
ध्यान दें कि निर्देशांक पहले से ही कैसे सही ढंग से सेट हैं! यदि आप अभी-अभी पास हुए हैं तो ऐसा नहीं होगा density
।
या इसका उपयोग करते एक और मजेदार उदाहरण देने के लिए astropy मॉडल (इस बार मैं निर्देशांक के बारे में ज्यादा परवाह नहीं है, मैं सिर्फ उन्हें बनाने के लिए उपयोग कुछ ग्रिड):
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)
हालाँकि यह केवल " दिखावे के लिए" है scipy.interpolate.interp2d
, कार्यात्मक मॉडल और फिटिंग से संबंधित कई कार्य (उदाहरण के लिए ,
scipy.interpolate.griddata
यहां तक कि उदाहरणों का उपयोग करके np.mgrid
) स्कैपी में, आदि के लिए ग्रिड की आवश्यकता होती है। इनमें से अधिकांश खुले ग्रिड और घने ग्रिड के साथ काम करते हैं, हालांकि कुछ केवल उनमें से एक के साथ काम करते हैं।
xx
औरyy
। मेरे लिए रहस्यमयी बात यह थी कि परिणाम की उस जोड़ी को वह क्यों लौटाता है, और वे क्या दिखते हैं। उसके लिए है फान का जवाब आसान है। मुझे लगता है कि यह सुविधा के लिए करता है, क्योंकि प्लॉट उस तरह के दो मापदंडों को चाहता है।