यह है कि कैसे सरणी आकार प्रसारण के लिए उन्नत अनुक्रमित का उपयोग करता है। जब आप 0पहले इंडेक्स के लिए पास होते हैं , और yआखिरी इंडेक्स के लिए, खसखस को 0उसी आकार में प्रसारित किया जाएगा y। निम्नलिखित समानता रखती है x[0,:,:,y] == x[(0, 0, 0),:,:,y]:। यहाँ एक उदाहरण है
import numpy as np
x = np.arange(120).reshape(2,3,4,5)
y = np.array([0,2,4])
np.equal(x[0,:,:,y], x[(0, 0, 0),:,:,y]).all()
# returns:
True
अब, क्योंकि आप प्रभावी रूप से सूचकांकों के दो सेटों में गुजर रहे हैं, तो आप सूचकांकों के जोड़े (इस मामले में) बनाने के लिए उन्नत अनुक्रमण एपीआई का उपयोग कर रहे हैं।
x[(0, 0, 0),:,:,y])
# equivalent to
[
x[0,:,:,y[0]],
x[0,:,:,y[1]],
x[0,:,:,y[2]]
]
# equivalent to
rows = np.array([0, 0, 0])
cols = y
x[rows,:,:,cols]
# equivalent to
[
x[r,:,:,c] for r, c in zip(rows, columns)
]
जिसका पहला आयाम है, जिसकी लंबाई समान है y। यह जो आप देख रहे हैं।
एक उदाहरण के रूप में, 4 आयामों के साथ एक सरणी को देखें जो अगले भाग में वर्णित हैं:
x = np.arange(120).reshape(2,3,4,5)
y = np.array([0,2,4])
# x looks like:
array([[[[ 0, 1, 2, 3, 4], -+ =+
[ 5, 6, 7, 8, 9], Sheet1 |
[ 10, 11, 12, 13, 14], | |
[ 15, 16, 17, 18, 19]], -+ |
Workbook1
[[ 20, 21, 22, 23, 24], -+ |
[ 25, 26, 27, 28, 29], Sheet2 |
[ 30, 31, 32, 33, 34], | |
[ 35, 36, 37, 38, 39]], -+ |
|
[[ 40, 41, 42, 43, 44], -+ |
[ 45, 46, 47, 48, 49], Sheet3 |
[ 50, 51, 52, 53, 54], | |
[ 55, 56, 57, 58, 59]]], -+ =+
[[[ 60, 61, 62, 63, 64],
[ 65, 66, 67, 68, 69],
[ 70, 71, 72, 73, 74],
[ 75, 76, 77, 78, 79]],
[[ 80, 81, 82, 83, 84],
[ 85, 86, 87, 88, 89],
[ 90, 91, 92, 93, 94],
[ 95, 96, 97, 98, 99]],
[[100, 101, 102, 103, 104],
[105, 106, 107, 108, 109],
[110, 111, 112, 113, 114],
[115, 116, 117, 118, 119]]]])
x अनुक्रमिक रूप को समझने में वास्तव में आसान है जिसे हम अब दिखाने के लिए उपयोग कर सकते हैं कि क्या हो रहा है ...
पहला आयाम 2 एक्सेल वर्कबुक होने जैसा है, दूसरा आयाम प्रत्येक वर्कबुक में 3 शीट होने जैसा है, तीसरा आयाम 4 शीट प्रति शीट की तरह है, और अंतिम आयाम प्रत्येक पंक्ति (या शीट प्रति कॉलम) के लिए 5 मान है।
इसे इस तरह से देखते हुए, पूछना x[0,:,:,0], यह कहना है: "पहली कार्यपुस्तिका में, प्रत्येक पत्रक के लिए, प्रत्येक पंक्ति के लिए, मुझे पहला मूल्य / स्तंभ दें।"
x[0,:,:,y[0]]
# returns:
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
# this is in the same as the first element in:
x[(0,0,0),:,:,y]
लेकिन अब उन्नत अनुक्रमण के साथ, हम x[(0,0,0),:,:,y]"पहली कार्यपुस्तिका में, प्रत्येक पत्रक के लिए, प्रत्येक पंक्ति के लिए, मुझे yवें मान / स्तंभ दे सकते हैं। ठीक है, अब इसे प्रत्येक मान के लिए कर सकते हैं y"।
x[(0,0,0),:,:,y]
# returns:
array([[[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]],
[[ 2, 7, 12, 17],
[22, 27, 32, 37],
[42, 47, 52, 57]],
[[ 4, 9, 14, 19],
[24, 29, 34, 39],
[44, 49, 54, 59]]])
जहां यह पागल हो जाता है कि इंडेक्स सरणी के बाहरी आयामों से मेल करने के लिए संख्यात्मक प्रसारित होगा । इसलिए यदि आप ऊपर भी वैसा ही ऑपरेशन करना चाहते हैं, लेकिन BOTH "एक्सेल वर्कबुक" के लिए, आपको लूप और कॉन्सिलेट नहीं करना है। आप केवल पहले आयाम के लिए एक सरणी पास कर सकते हैं, लेकिन यह एक सुसंगत आकार होना चाहिए ।
पूर्णांक पास करने से प्रसारण हो जाता है y.shape == (3,)। यदि आप किसी सरणी को पहले सूचकांक के रूप में पास करना चाहते हैं, तो सरणी के अंतिम आयाम के साथ संगत होना चाहिए y.shape। यानी, पहले इंडेक्स का अंतिम आयाम या तो 3 या 1 होना चाहिए।
ix = np.array([[0], [1]])
x[ix,:,:,y].shape
# each row of ix is broadcast to length 3:
(2, 3, 3, 4)
ix = np.array([[0,0,0], [1,1,1]])
x[ix,:,:,y].shape
# this is identical to above:
(2, 3, 3, 4)
ix = np.array([[0], [1], [0], [1], [0]])
x[ix,:,:,y].shape
# ix is broadcast so each row of ix has 3 columns, the length of y
(5, 3, 3, 4)
डॉक्स में संक्षिप्त विवरण मिला: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
संपादित करें:
मूल प्रश्न से, अपनी इच्छित सदस्यता का एक-लाइनर प्राप्त करने के लिए, आप इसका उपयोग कर सकते हैं x[0][:,:,y]:
x[0][:,:,y].shape
# returns
(2, 50, 3)
हालांकि, यदि आप उन उप-वर्गों को निर्दिष्ट करने का प्रयास कर रहे हैं, तो आपको बहुत सावधान रहना होगा कि आप मूल सरणी के साझा स्मृति दृश्य को देख रहे हैं। अन्यथा असाइनमेंट मूल सरणी के लिए नहीं होगा, बल्कि एक कॉपी होगा।
साझा की गई मेमोरी केवल तब होती है जब आप अपने एरे को कम करने के लिए एक पूर्णांक या स्लाइस का उपयोग करते हैं, x[:,0:3,:,:]या x[0,:,:,1:-1]।
np.shares_memory(x, x[0])
# returns:
True
np.shares_memory(x, x[:,:,:,y])
# returns:
False
आपके मूल प्रश्न और मेरे उदाहरण दोनों yमें न तो कोई इंट या स्लाइस है, इसलिए हमेशा मूल की एक कॉपी को असाइन करना होगा।
परंतु! क्योंकि आपके सरणी yको एक स्लाइस के रूप में व्यक्त किया जा सकता है, आप वास्तव में अपने सरणी के माध्यम से एक देखने योग्य दृश्य प्राप्त कर सकते हैं :
x[0,:,:,0:21:10].shape
# returns:
(2, 50, 3)
np.shares_memory(x, x[0,:,:,0:21:10])
# returns:
True
# actually assigns to the original array
x[0,:,:,0:21:10] = 100
यहां हम 0:21:10प्रत्येक इंडेक्स को खींचने के लिए स्लाइस का उपयोग करते हैं जो अंदर होगा range(0,21,10)। हमें उपयोग करना है 21और नहीं 20क्योंकि स्टॉप-पॉइंट को स्लाइस से बाहर रखा गया है, जैसे rangeफ़ंक्शन में।
तो मूल रूप से, यदि आप एक स्लाइस का निर्माण कर सकते हैं जो आपके निर्बल मानदंडों को पूरा करता है, तो आप असाइनमेंट कर सकते हैं।