1. NumPy में आकृतियों का अर्थ
आप लिखते हैं, "मुझे पता है कि यह वास्तव में संख्याओं की सूची है और उन सूचियों की सूची है जहां सभी सूची में केवल एक संख्या होती है" लेकिन इसके बारे में सोचने के लिए एक अनछुआ तरीका है।
NumPy सरणियों के बारे में सोचने का सबसे अच्छा तरीका यह है कि वे दो भागों से मिलकर बने होते हैं, एक डेटा बफर जो सिर्फ कच्चे तत्वों का एक ब्लॉक होता है, और एक दृश्य जो डेटा बफर की व्याख्या करने का तरीका बताता है।
उदाहरण के लिए, यदि हम 12 पूर्णांक बनाते हैं:
>>> a = numpy.arange(12)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
फिर a
एक डेटा बफर के होते हैं, इस तरह से कुछ व्यवस्था की:
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
और एक दृश्य जो डेटा की व्याख्या करने का तरीका बताता है:
>>> a.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
>>> a.dtype
dtype('int64')
>>> a.itemsize
8
>>> a.strides
(8,)
>>> a.shape
(12,)
यहाँ आकृति का (12,)
अर्थ है कि सरणी को एक एकल सूचकांक द्वारा अनुक्रमित किया जाता है जो 0 से 11. तक चलता है। यदि हम इस एकल सूचकांक को लेबल करते हैं i
, तो सरणी a
इस तरह दिखता है:
i= 0 1 2 3 4 5 6 7 8 9 10 11
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
यदि हम किसी सरणी को फिर से खोलते हैं , तो यह डेटा बफर को नहीं बदलता है। इसके बजाय, यह एक नया दृष्टिकोण बनाता है जो डेटा की व्याख्या करने का एक अलग तरीका बताता है। इतना होने के बाद:
>>> b = a.reshape((3, 4))
सरणी b
में डेटा बफ़र के समान है a
, लेकिन अब इसे दो सूचकांकों द्वारा अनुक्रमित किया जाता है जो क्रमशः 0 से 2 और 0 से 3 तक चलते हैं। यदि हम दो सूचकांकों को लेबल करते हैं i
और j
, सरणी b
इस तरह दिखता है:
i= 0 0 0 0 1 1 1 1 2 2 2 2
j= 0 1 2 3 0 1 2 3 0 1 2 3
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
जिसका मतलब है कि:
>>> b[2,1]
9
आप देख सकते हैं कि दूसरा सूचकांक जल्दी बदलता है और पहला सूचकांक धीरे-धीरे बदलता है। यदि आप इसे दूसरे तरीके से पसंद करते हैं, तो आप order
पैरामीटर निर्दिष्ट कर सकते हैं :
>>> c = a.reshape((3, 4), order='F')
इस तरह से अनुक्रमित सरणी में कौन से परिणाम हैं:
i= 0 1 2 0 1 2 0 1 2 0 1 2
j= 0 0 0 1 1 1 2 2 2 3 3 3
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
जिसका मतलब है कि:
>>> c[2,1]
5
यह अब स्पष्ट होना चाहिए कि किसी सरणी के लिए आकार के एक या अधिक आयामों के साथ इसका क्या अर्थ है। 1. बाद में:
>>> d = a.reshape((12, 1))
सरणी d
को दो सूचकांकों द्वारा अनुक्रमित किया जाता है, जिनमें से पहला 0 से 11 तक चलता है, और दूसरा सूचकांक हमेशा 0 होता है:
i= 0 1 2 3 4 5 6 7 8 9 10 11
j= 0 0 0 0 0 0 0 0 0 0 0 0
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
इसलिए:
>>> d[10,0]
10
लंबाई 1 का आयाम "मुक्त" (कुछ अर्थों में) है, इसलिए आपको शहर जाने से कुछ भी नहीं रोक सकता है:
>>> e = a.reshape((1, 2, 1, 6, 1))
इस तरह अनुक्रमित सरणी देना:
i= 0 0 0 0 0 0 0 0 0 0 0 0
j= 0 0 0 0 0 0 1 1 1 1 1 1
k= 0 0 0 0 0 0 0 0 0 0 0 0
l= 0 1 2 3 4 5 0 1 2 3 4 5
m= 0 0 0 0 0 0 0 0 0 0 0 0
┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
इसलिए:
>>> e[0,1,0,0,0]
6
कैसे सरणियाँ कार्यान्वित की जाती हैं, इस बारे में अधिक जानकारी के लिए NumPy के आंतरिक दस्तावेज़ देखें ।
2. क्या करना है?
चूंकि numpy.reshape
बस एक नया दृश्य बनाता है, आपको जब भी आवश्यक हो इसका उपयोग करने के बारे में डर नहीं होना चाहिए। जब आप किसी सरणी को किसी भिन्न तरीके से अनुक्रमित करना चाहते हैं, तो इसका उपयोग करने का सही उपकरण है।
हालांकि, एक लंबी गणना में आमतौर पर पहली जगह में "सही" आकार के साथ सरणियों का निर्माण करना संभव होता है, और इसलिए फेरबदल और स्थानांतरित करने की संख्या को कम करता है। लेकिन वास्तविक संदर्भ को देखने के बिना, जिसे पुनर्वसन की आवश्यकता के कारण, यह कहना मुश्किल है कि क्या बदलना चाहिए।
आपके प्रश्न में उदाहरण है:
numpy.dot(M[:,0], numpy.ones((1, R)))
लेकिन यह यथार्थवादी नहीं है। सबसे पहले, यह अभिव्यक्ति:
M[:,0].sum()
परिणाम को अधिक सरल रूप से गणना करता है। दूसरा, क्या स्तंभ 0 के बारे में वास्तव में कुछ खास है? शायद आपको वास्तव में क्या चाहिए:
M.sum(axis=0)