2016-07-29 5 views
5

में उपयोग किया गया है मेरे पास 2 डी सर v, v.shape=(M_1,M_2) है, जिसे मैं v.shape=(M_2,N_1,N_2), और M_1=N_1*N_2 के साथ 3 डी सरणी में दोबारा बदलना चाहता हूं। reshape_tuple=(M_2,N_1,N_2) के लिएपायथन रावेल बनाम ट्रांसफर जब रीशेप

np.reshape(v.T, reshape_tuple) 

और

np.reshape(v.ravel(order='F'), reshape_tuple) 

:

मैं निम्नलिखित लाइनों जो एक ही परिणाम उपज के साथ आया था।

कौन सा कम्प्यूटेशनल रूप से बेहतर है और किस अर्थ में (कंप टाइम, मेमोरी इत्यादि) यदि मूल v एक विशाल (संभवतः जटिल मूल्यवान) मैट्रिक्स है?

मेरा अनुमान होगा कि पक्षांतरित का उपयोग कर बेहतर है, लेकिन अगर reshape एक स्वत: ravel तो करता है हो सकता है फैलना-विकल्प तेजी से होता है (हालांकि reshape सी या फोरट्रान में ravel कर किया जा सकता है और उसके बाद यह स्पष्ट नहीं है)?

उत्तर

3

ऑर्डर जिसमें वे चीजें करते हैं - दोबारा बदलें, कदम बदलें, और प्रतिलिपि बनाएं - अलग-अलग हैं, लेकिन वे वही काम करते हैं।

मुझे डेटा बफर कहां स्थित है, और अन्य परिवर्तनों को देखने के लिए __array_interface__ का उपयोग करना पसंद है। मुझे लगता है कि order देखने के लिए मुझे flags जोड़ना चाहिए। लेकिन हम/आप जानते हैं कि transpose पहले से ही F पर ऑर्डर बदलता है, है ना?

In [549]: x=np.arange(6).reshape(2,3) 
In [550]: x.__array_interface__ 
Out[550]: 
{'data': (187732024, False), 
'descr': [('', '<i4')], 
'shape': (2, 3), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 

पक्षांतरित एक दृश्य है, विभिन्न आकार, प्रगति और आदेश के साथ:

क्रम भिन्न है
In [551]: x.T.__array_interface__ 
Out[551]: 
{'data': (187732024, False), 
'descr': [('', '<i4')], 
'shape': (3, 2), 
'strides': (4, 12), 
'typestr': '<i4', 
'version': 3} 

फैलना एक प्रति (अलग डेटा बफर सूचक) है

In [552]: x.ravel(order='F').__array_interface__ 
Out[552]: 
{'data': (182286992, False), 
'descr': [('', '<i4')], 
'shape': (6,), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 

पक्षांतरित फैलना है एक प्रति भी। मुझे लगता है कि वही डेटा पॉइंटर केवल स्मृति पुन: उपयोग का मामला है (क्योंकि मैं एक चर को असाइन नहीं कर रहा हूं) - लेकिन इसकी जांच की जा सकती है।

In [554]: x.T.ravel().reshape(2,3).__array_interface__ 
Out[554]: 
{'data': (182286992, False), 
'descr': [('', '<i4')], 
'shape': (2, 3), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 
In [555]: x.ravel(order='F').reshape(2,3).__array_interface__ 
Out[555]: 
{'data': (182286992, False), 
'descr': [('', '<i4')], 
'shape': (2, 3), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 

मुझे लगता है कि वहाँ एक अंतर्निहित आकृति बदलें में 'प्रसिद्ध हो जाना' है::

In [553]: x.T.ravel().__array_interface__ 
Out[553]: 
{'data': (182286992, False), 
'descr': [('', '<i4')], 
'shape': (6,), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 

आकृति बदलें जोड़ने

In [558]: x.T.reshape(2,3).__array_interface__ 
Out[558]: 
{'data': (182286992, False), 
'descr': [('', '<i4')], 
'shape': (2, 3), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 

(मैं इन उदाहरणों rework चाहिए कि स्मृति पुन: उपयोग अस्पष्टता से छुटकारा पाने के ।) किसी भी मामले में, स्थानांतरण के बाद दोबारा बदलने के लिए एक ही स्मृति प्रतिलिपि की आवश्यकता होती है जो आदेश परिवर्तन के साथ एक रेलवे करता है। और जहां तक ​​मैं कह सकता हूं कि किसी भी मामले के लिए केवल एक प्रतिलिपि की आवश्यकता है। अन्य परिचालनों में केवल आकार जैसे गुणों में परिवर्तन शामिल हैं।

हो सकता है यह स्पष्ट है कि अगर हम सिर्फ सरणियों

In [565]: x.T 
Out[565]: 
array([[0, 3], 
     [1, 4], 
     [2, 5]]) 

T हम अभी भी सांख्यिक क्रम में सरणी के माध्यम से कदम सकते हैं देखो। लेकिन reshape के बाद, 10 के करीब कहीं भी नहीं है। स्पष्ट रूप से एक प्रतिलिपि बनाई गई है।

In [566]: x.T.reshape(2,3) 
Out[566]: 
array([[0, 3, 1], 
     [4, 2, 5]]) 

रावेल के समान मूल्यों के क्रम के समान मूल्य, और अधिक स्पष्ट रूप से reshape के बाद।

In [567]: x.ravel(order='F') 
Out[567]: array([0, 3, 1, 4, 2, 5]) 
In [568]: x.ravel(order='F').reshape(2,3) 
Out[568]: 
array([[0, 3, 1], 
     [4, 2, 5]]) 
+0

ठीक है, मैं देखता हूं, इसलिए ऐसा लगता है कि यह वास्तव में कोई फर्क नहीं पड़ता कि मैं क्या चुनता हूं। धन्यवाद! –

+0

दिलचस्प बात यह है कि समय दिखाता है कि np.reshape (v.T, reshape_tuple) np.reshape (v.ravel (order = 'f'), reshape_tuple से बहुत तेज है)। –

+0

शायद 'reshape_tuple' ऐसा है कि' np.reshape (v.T, reshape_tuple) को कॉपी करने की आवश्यकता नहीं है। यही है, नया आकार ट्रांसपोज़ड आकार के साथ संगत है। मैं '__array_interface__' की जांच करूंगा। – hpaulj

संबंधित मुद्दे