जवाबों:
>>> test[:,0]
array([1, 3, 5])
इसी तरह,
>>> test[1,:]
array([3, 4])
आप पंक्तियों का उपयोग कर सकते हैं। यह NumPy संदर्भ की धारा 1.4 (अनुक्रमण) में शामिल है । यह त्वरित है, कम से कम मेरे अनुभव में। यह निश्चित रूप से लूप में प्रत्येक तत्व तक पहुंचने की तुलना में बहुत तेज है।
और यदि आप एक बार में एक से अधिक कॉलम एक्सेस करना चाहते हैं, तो आप कर सकते हैं:
>>> test = np.arange(9).reshape((3,3))
>>> test
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> test[:,[0,2]]
array([[0, 2],
[3, 5],
[6, 8]])
test[:,[0,2]]
बस डेटा तक पहुँचता है, उदाहरण के लिए, test[:, [0,2]] = something
परीक्षण को संशोधित करेगा, और दूसरा सरणी नहीं बनाएगा। लेकिन copy_test = test[:, [0,2]]
वास्तव में जैसा कि आप कहते हैं एक प्रति बनाएँ।
test[:,[0,2]]
सिर्फ डेटा तक पहुंच क्यों test[:, [0, 2]][:, [0, 1]]
नहीं है? यह बहुत ही अनपेक्षित लगता है कि एक ही काम करने का फिर से एक अलग परिणाम होता है।
>>> test[:,0]
array([1, 3, 5])
यह कमांड आपको एक पंक्ति सदिश देता है, यदि आप बस उस पर लूप करना चाहते हैं, तो यह ठीक है, लेकिन यदि आप आयाम 3xN के साथ कुछ अन्य सरणी के साथ रुकना चाहते हैं, तो आपके पास होगा
ValueError: all the input arrays must have same number of dimensions
जबकि
>>> test[:,[0]]
array([[1],
[3],
[5]])
आपको एक कॉलम वेक्टर देता है, ताकि आप कॉन्टेनेट या हाईस्टैक ऑपरेशन कर सकें।
जैसे
>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
[3, 4, 3],
[5, 6, 5]])
कई और अयोग्य कॉलम प्राप्त करने के लिए, बस:
> test[:,[0,2]]
आपको कोलम 0 और 2 मिलेंगे
यद्यपि प्रश्न का उत्तर दिया गया है, लेकिन मुझे कुछ बारीकियों का उल्लेख करना चाहिए।
मान लें कि आप सरणी के पहले कॉलम में रुचि रखते हैं
arr = numpy.array([[1, 2],
[3, 4],
[5, 6]])
जैसा कि आप पहले से ही अन्य उत्तरों से जानते हैं, इसे "पंक्ति वेक्टर" (आकार की सरणी (3,)
) के रूप में प्राप्त करने के लिए , आप स्लाइसिंग का उपयोग करते हैं:
arr_c1_ref = arr[:, 1] # creates a reference to the 1st column of the arr
arr_c1_copy = arr[:, 1].copy() # creates a copy of the 1st column of the arr
यह जाँचने के लिए कि एक सरणी एक दृश्य है या किसी अन्य सरणी की प्रतिलिपि आप निम्न कार्य कर सकते हैं:
arr_c1_ref.base is arr # True
arr_c1_copy.base is arr # False
ndarray.base देखें ।
दोनों के बीच स्पष्ट अंतर के अलावा (संशोधन arr_c1_ref
को प्रभावित करेगा arr
), उनमें से प्रत्येक को ट्रैवर्स करने के लिए बाइट-चरणों की संख्या अलग है:
arr_c1_ref.strides[0] # 8 bytes
arr_c1_copy.strides[0] # 4 bytes
देख प्रगति । यह महत्वपूर्ण क्यों है? कल्पना करें कि आपके पास A
इसके बजाय एक बहुत बड़ी सरणी है arr
:
A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1]
A_c1_copy = A[:, 1].copy()
और आप पहले कॉलम के सभी तत्वों के योग की गणना करना चाहते हैं, A_c1_ref.sum()
या A_c1_copy.sum()
। प्रतिलिपि किए गए संस्करण का उपयोग करना बहुत तेज़ है:
%timeit A_c1_ref.sum() # ~248 µs
%timeit A_c1_copy.sum() # ~12.8 µs
यह पहले उल्लिखित स्ट्राइड्स की विभिन्न संख्याओं के कारण है:
A_c1_ref.strides[0] # 40000 bytes
A_c1_copy.strides[0] # 4 bytes
यद्यपि यह लग सकता है कि कॉलम प्रतियों का उपयोग करना बेहतर है, यह हमेशा इस कारण से सही नहीं है कि प्रतिलिपि बनाने में समय लगता है और अधिक मेमोरी का उपयोग करता है (इस मामले में मुझे लगभग 200 using बनाने के लिए लगभग A_c1_copy
) लिया गया है। हालाँकि, अगर हमें पहली जगह में कॉपी की आवश्यकता है, या हमें सरणी के एक विशिष्ट कॉलम पर कई अलग-अलग ऑपरेशन करने की आवश्यकता है और हम गति के लिए स्मृति का त्याग करने के साथ ठीक हैं, तो प्रतिलिपि बनाना एक रास्ता है।
उस स्थिति में जब हम अधिकतर स्तंभों के साथ काम करने में रुचि रखते हैं, यह पंक्ति-प्रमुख ('C') क्रम के बजाय स्तंभ-प्रमुख ('F') क्रम में हमारे सरणी बनाने के लिए एक अच्छा विचार हो सकता है (जो कि डिफ़ॉल्ट है ), और फिर एक प्रतिलिपि प्राप्त करने के बिना एक कॉलम प्राप्त करने के लिए पहले की तरह स्लाइसिंग करें:
A = np.asfortranarray(A) # or np.array(A, order='F')
A_c1_ref = A[:, 1]
A_c1_ref.strides[0] # 4 bytes
%timeit A_c1_ref.sum() # ~12.6 µs vs ~248 µs
अब, कॉलम-व्यू पर राशि संचालन (या किसी अन्य) का प्रदर्शन बहुत तेज है।
अंत में मुझे ध्यान दें कि एक सरणी को ट्रांसपोज़ करना और पंक्ति-स्लाइसिंग का उपयोग करना मूल स्तंभ पर कॉलम-स्लाइसिंग का उपयोग करने के समान है, क्योंकि ट्रांसपोज़िंग केवल आकृति और मूल सरणी के स्ट्रैप को स्वैप करके किया जाता है।
A.T[1,:].strides[0] # 40000