NumPy का स्थानान्तरण () विधि किसी सरणी के अक्षों को कैसे पार करती है?


81
In [28]: arr = np.arange(16).reshape((2, 2, 4))

In [29]: arr
Out[29]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])


In [32]: arr.transpose((1, 0, 2))
Out[32]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

जब हम transpose()फंक्शन में पूर्णांकों का एक समूह पास करते हैं, तो क्या होता है?

विशिष्ट होने के लिए, यह एक 3D सरणी है: जब मैं कुल्हाड़ियों के गुच्छे से गुजरता हूं, तो NumP कैसे सरणी को परिवर्तित करता है (1, 0 ,2)? क्या आप बता सकते हैं कि ये पूर्णांक किस पंक्ति या स्तंभ को संदर्भित करते हैं? और NumPy के संदर्भ में अक्ष संख्याएँ क्या हैं?



2
0पहली धुरी है, 1दूसरी है, 2तीसरी है, आदि ... नया ऑर्डर प्रदान axesकरने के लिए पैरामीटर transposeआप उन्हें अपने उदाहरण में व्यवस्थित करना चाहते हैं: पहले दूसरा, फिर पहला, फिर तीसरा।
Jaime

3 डी डिस्प्ले में ब्लॉक, रो और कॉलम होते हैं। आपके स्थानांतरण ने कॉलम और पंक्तियों के क्रम को बदल दिया है, जिससे कॉलम अपरिवर्तित रह गए हैं। क्या 1 ब्लॉक की दूसरी पंक्ति हुआ करती थी, दूसरी ब्लॉक की पहली पंक्ति बन जाती है।
हंपुलज

जवाबों:


190

किसी सरणी को स्थानांतरित करने के लिए, NumPy बस आकृति को स्वैप करता है और प्रत्येक अक्ष के लिए जानकारी को स्ट्रेट करता है। यहाँ स्ट्राइड हैं:

>>> arr.strides
(64, 32, 8)

>>> arr.transpose(1, 0, 2).strides
(32, 64, 8)

ध्यान दें कि पारगमन ऑपरेशन ने अक्ष 0 और अक्ष के लिए तारों की अदला-बदली की। 1. इन अक्षों की लंबाई भी अदला-बदली की गई (दोनों लंबाई 2इस उदाहरण में हैं)।

ऐसा होने के लिए किसी भी डेटा को कॉपी करने की आवश्यकता नहीं है; NumPy बस बदल सकता है कि नए एरो को बनाने के लिए अंतर्निहित मेमोरी को कैसे देखता है।


विजुअलिंग स्ट्राइड्स

स्ट्राइड मान बाइट्स की संख्या को दर्शाता है जो किसी सरणी के अक्ष के अगले मूल्य तक पहुंचने के लिए मेमोरी में यात्रा की जानी चाहिए।

अब, हमारा 3D सरणी arrयह दिखता है (लेबल वाले कुल्हाड़ियों के साथ):

यहाँ छवि विवरण दर्ज करें

यह सरणी मेमोरी के एक सन्निहित ब्लॉक में संग्रहीत है ; अनिवार्य रूप से यह एक आयामी है। इसे 3 डी ऑब्जेक्ट के रूप में व्याख्या करने के लिए, NumPy को तीन अक्षों में से एक के साथ जाने के लिए बाइट्स की एक निश्चित स्थिर संख्या पर कूदना चाहिए:

यहाँ छवि विवरण दर्ज करें

चूँकि प्रत्येक पूर्णांक मेमोरी के 8 बाइट्स लेता है (हम int64 dtype का उपयोग कर रहे हैं), प्रत्येक आयाम के लिए स्ट्राइड वैल्यू उन मानों की संख्या से 8 गुना है, जिन्हें हमें कूदने की आवश्यकता है। उदाहरण के लिए, अक्ष 1 के साथ जाने के लिए, चार मान (32 बाइट्स) जंप किए जाते हैं, और अक्ष 0 के साथ जाने के लिए, आठ मान (64 बाइट) को कूदने की आवश्यकता होती है।

जब हम लिखते हैं कि arr.transpose(1, 0, 2)हम कुल्हाड़ियों की अदला-बदली कर रहे हैं 0 और 1. ट्रांसपोज़्ड सरणी इस तरह दिखती है:

यहाँ छवि विवरण दर्ज करें

NumPy को जो कुछ करने की ज़रूरत है वह अक्ष 0 और अक्ष 1 (अक्ष 2 अपरिवर्तित) के लिए स्ट्राइड जानकारी को स्वैप करना है। अब हमें अक्ष 0 के साथ अक्ष 1 पर जाने के लिए आगे कूदना चाहिए:

यहाँ छवि विवरण दर्ज करें

यह मूल अवधारणा किसी सरणी के अक्षों के किसी भी क्रमचय के लिए काम करती है। वास्तविक कोड जो ट्रांसपोज़ को हैंडल करता है वह C में लिखा गया है और यहां पाया जा सकता है


7

जैसा कि प्रलेखन में बताया गया है :

डिफ़ॉल्ट रूप से, आयामों को उल्टा करें, अन्यथा दिए गए मूल्यों के अनुसार कुल्हाड़ियों को अनुमति दें।

तो आप axesआयामों के नए क्रम को परिभाषित करने वाला एक वैकल्पिक पैरामीटर पास कर सकते हैं ।

उदाहरण के लिए आरजीबी वीजीए पिक्सेल सरणी के पहले दो आयामों को बदलना:

 >>> x = np.ones((480, 640, 3))
 >>> np.transpose(x, (1, 0, 2)).shape
 (640, 480, 3)

1
नमस्ते, आपके उत्तर के लिए धन्यवाद। हालाँकि, मैं अभी भी इस समस्या को नहीं समझ सकता हूँ, जैसा कि आप देख सकते हैं, गिरफ्तारी का आकार (2,2,4) है और arr.transpose (1,0,2) है (2,2,4) भी। इसके लिए निर्दिष्ट करें, यह एक 3-डी सरणी है, जब मैं (1,0,2) पास करता हूं, तो सरणी को कैसे बदलना है, क्या आप समझा सकते हैं कि 1,0,2,2 को किस पंक्ति या कॉलम में रखा जाए? और संख्या के संदर्भ में अक्ष संख्या क्या है?
फ्रैंक हू

1
@FrankHu 3 डी अंतरिक्ष में कल्पना करता है, इसलिए एक्स, वाई अक्ष रोटेशन यहां क्या हुआ है। (1,0,2) को (0,1,2) से ट्रांसपोज़ किया गया था, इसलिए, पहले 2 अक्ष को स्विच किया जाता है। 0 अक्ष की सूचकांक संख्या है। कहें, x, y, z मैप्स 0,1,2
CodeFarmer

5

C संकेतन में, आपकी सरणी होगी:

int arr[2][2][4]

जो एक 3D सरणी है जिसमें 2 डी सरणियाँ हैं। उन 2 डी सरणियों में से प्रत्येक में 2 1D सरणी है, उन 1D सरणियों में से प्रत्येक में 4 तत्व हैं।

तो आपके तीन आयाम हैं। कुल्हाड़ियों 0, 1, 2 हैं, आकार 2, 2, 4 के साथ। यह ठीक उसी तरह है जैसे कि एन-आयामी सरणी के कुल्हाड़ियों को सुन्न मानते हैं।

तो, arr.transpose((1, 0, 2))अक्ष 1 ले जाएगा और इसे स्थिति 0, अक्ष 0 में रख देगा और इसे स्थिति 1 में रख देगा, और अक्ष 2 और इसे स्थिति 2 में छोड़ देगा। आप प्रभावी रूप से अक्षों को अनुमति दे रहे हैं:

0 -\/-> 0
1 -/\-> 1
2 ----> 2

दूसरे शब्दों में, 1 -> 0, 0 -> 1, 2 -> 2। गंतव्य अक्ष हमेशा क्रम में होते हैं, इसलिए आपको स्रोत अक्षों को निर्दिष्ट करने की आवश्यकता होती है। उस क्रम में ट्यूपल को पढ़ें (1, 0, 2):।

इस मामले में आपके नए सरणी आयाम फिर से हैं [2][2][4], केवल इसलिए कि कुल्हाड़ियों 0 और 1 का आकार समान था (2)।

अधिक दिलचस्प एक संक्रमण है (2, 1, 0)जिसके द्वारा आपको एक सरणी मिलती है [4][2][2]

0 -\ /--> 0
1 --X---> 1
2 -/ \--> 2

दूसरे शब्दों में, 2 -> 0, 1 -> 1, 0 -> 2। उस क्रम में ट्यूपल को पढ़ें (2, 1, 0):।

>>> arr.transpose((2,1,0))
array([[[ 0,  8],
        [ 4, 12]],

       [[ 1,  9],
        [ 5, 13]],

       [[ 2, 10],
        [ 6, 14]],

       [[ 3, 11],
        [ 7, 15]]])

आप एक के साथ समाप्त हुआ int[4][2][2]

यदि सभी आयाम अलग-अलग आकार के होते हैं, तो आप शायद बेहतर समझ पाएंगे, इसलिए आप देख सकते हैं कि प्रत्येक अक्ष कहां गया।

पहला आंतरिक तत्व क्यों है [0, 8]? क्योंकि यदि आप अपने 3D सरणी को कागज की दो शीट के रूप में देखते हैं , 0और 8पंक्तिबद्ध हैं, एक कागज पर और दूसरा कागज पर, दोनों ऊपरी बाएँ में। ट्रांसपोज़ करके (2, 1, 0)आप कह रहे हैं कि आप पेपर-टू-पेपर की दिशा चाहते हैं कि अब पेपर को बाएं से दाएं, और बाएं से दाएं की दिशा में पेपर से पेपर पर जाएं। आपके पास 4 तत्व बाएं से दाएं जा रहे थे, इसलिए अब आपके पास कागज के चार टुकड़े हैं। और आपके पास 2 पेपर थे, इसलिए अब आपके पास 2 तत्व हैं जो बाएं से दाएं जा रहे हैं।

भयानक ASCII कला के लिए क्षमा करें। ¯\_(ツ)_/¯


क्या मैं यह सोचने में सही हूं कि आप जो टपल दे रहे हैं transpose()वह गणितीय क्रमपरिवर्तन या कुछ भी नहीं है? यह शाब्दिक रूप से निर्देश है कि "इन पदों पर अब कुल्हाड़ी बनाओ"? उदाहरण के लिए .transpose(p, q, r, s)आप कह रहे हैं "अक्ष pको 0 वें के qरूप में, 1 के rरूप में , 2 के sरूप में और 3 के रूप में रखें"? या किसी अन्य तरीके से देखा b = a.transpose(axes)साधन b.shape == tuple(a.shape[i] for i in axes)?
टिम

ASCII कला के साथ अक्ष को स्वैप करने का विचार मेरी समझ को स्पष्ट करता है। बहुत बहुत धन्यवाद
K_inverse

0

ऐसा लगता है कि प्रश्न और उदाहरण वेस मैककिनी द्वारा डेटा विश्लेषण के लिए पायथन पुस्तक से उत्पन्न हुआ है । अध्याय 4.1transpose में इस विशेषता का उल्लेख है । ट्रांसपेरिंग एरेस और स्वैपिंग एक्सिस

उच्च आयामी सरणियों के लिए, transposeकुल्हाड़ियों को अनुमति देने के लिए अक्षों की संख्या का एक tuple स्वीकार करेंगे (अतिरिक्त दिमाग झुकने के लिए)।

यहां "परमिट" का अर्थ "पुनर्व्यवस्थित करना" है, इसलिए कुल्हाड़ियों के क्रम को फिर से व्यवस्थित करना।

यह .transpose(1, 0, 2)निर्धारित करता है कि मूल की तुलना में कुल्हाड़ियों के क्रम को कैसे बदला जाता है। उपयोग करने .transpose(1, 0, 2)से हमारा मतलब है, "1 कुल्हाड़ी को 2 के साथ बदलें।" यदि हम उपयोग करते हैं .transpose(0, 1, 2), तो सरणी वही रहेगी क्योंकि बदलने के लिए कुछ भी नहीं है; यह डिफ़ॉल्ट क्रम है।

(2, 2, 4)1 और 2 कुल्हाड़ियों के आकार समान होने से आकार सरणी के साथ पुस्तक में उदाहरण बहुत स्पष्ट नहीं है। तो अंत परिणाम पंक्तियों के पुन: क्रमांकन को छोड़कर नहीं लगता है arr[0, 1]और arr[1, 0]

यदि हम 3 आयाम सरणी के साथ एक अलग उदाहरण की कोशिश करते हैं, जिसमें प्रत्येक आयाम का एक अलग आकार होता है, तो पुनर्व्यवस्था वाला भाग अधिक स्पष्ट हो जाता है।

In [2]: x = np.arange(24).reshape(2, 3, 4)

In [3]: x
Out[3]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [4]: x.transpose(1, 0, 2)
Out[4]: 
array([[[ 0,  1,  2,  3],
        [12, 13, 14, 15]],

       [[ 4,  5,  6,  7],
        [16, 17, 18, 19]],

       [[ 8,  9, 10, 11],
        [20, 21, 22, 23]]])

यहाँ, मूल सरणी आकार हैं (2, 3, 4)। हमने 1 और 2 को बदल दिया है, इसलिए यह (3, 2, 4)आकार में हो जाता है। यदि हम यह देखने के लिए करीब से देखें कि पुनर्व्यवस्था कैसे हुई; संख्याओं के सरणियों को एक विशेष पैटर्न में परिवर्तित किया गया लगता है। @ रॉबर्टबी के पेपर सादृश्य का उपयोग करते हुए , यदि हमें संख्याओं के 2 भाग लेने थे, और शीट पर प्रत्येक को लिखना था, तो सरणी के एक आयाम का निर्माण करने के लिए प्रत्येक शीट से एक पंक्ति लें, अब हमारे पास एक 3x2x4 आकार का सरणी होगा , सबसे बाहरी परत से सबसे ऊपर की गिनती।

[ 0,  1,  2,  3] \ [12, 13, 14, 15]

[ 4,  5,  6,  7] \ [16, 17, 18, 19]

[ 8,  9, 10, 11] \ [20, 21, 22, 23]

विभिन्न आकार के सरणियों के साथ खेलना और विभिन्न अक्षों को बदलना एक बेहतर विचार हो सकता है कि यह कैसे काम करता है का एक बेहतर अंतर्ज्ञान प्राप्त करने के लिए।


-3

संक्षेप में a.transpose () [i, j, k] = a [k, j, i]

a = np.array( range(24), int).reshape((2,3,4))
a.shape gives (2,3,4)
a.transpose().shape gives (4,3,2)  shape tuple is reversed.

जब एक ट्यूपल पैरामीटर पारित किया जाता है तो कुल्हाड़ियों को ट्यूपल के अनुसार अनुमति दी जाती है। उदाहरण के लिए

a = np.array (रेंज (24), int) .reshape ((2,3,4))

a [i, j, k] बराबर होता है aransrans ((2,0,1)) [k, i, j]

धुरी 0 दूसरा स्थान लेती है

अक्ष 1, 3 स्थान लेता है

अक्ष 2 किस्से 1 स्थान

निश्चित रूप से हमें यह ध्यान रखना चाहिए कि संक्रमण के लिए उत्तीर्ण टपल पैरामीटर में मान अद्वितीय और सीमा में हैं (अक्ष की संख्या)


आपने ओपी के प्रश्न को संबोधित नहीं किया है, जो तब होता है जब आप निर्दिष्ट अक्षों के साथ स्थानांतरित करते हैं
रॉबर्ट बी

जब कुल्हाड़ियों को निर्दिष्ट किया जाता है तो सवाल का जवाब दिया जाता है।
रघु राम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.