2015-07-23 7 views
6
arr = np.arange(0,11) 
slice_of_arr = arr[0:6] 
slice_of_arr[:]=99 

# slice_of_arr returns 
array([99, 99, 99, 99, 99, 99]) 
# arr returns 
array([99, 99, 99, 99, 99, 99, 6, 7, 8, 9, 10]) 

ऊपर दिखाए गए उदाहरण के रूप में, आप नहीं सीधे slice_of_arr के मूल्य बदल सकते हैं, क्योंकि यह एक नया वेरिएबल arr के एक दृश्य, नहीं है।NumPy: स्पष्ट रूप से मूल्य की प्रतिलिपि बनाने की आवश्यकता क्यों है?

मेरे प्रश्न हैं:

  1. क्यों इस तरह NumPy डिजाइन करता है? क्या आपको हर बार .copy की आवश्यकता होगी और फिर मान असाइन करें?
  2. क्या मैं, क्या कर सकते हैं .copy से छुटकारा पाने के है? मैं NumPy के इस डिफ़ॉल्ट व्यवहार को कैसे बदल सकता हूं?
+9

यह प्रदर्शन के लिए इस तरह डिज़ाइन किया गया है, और कार्यान्वित करना उदा। कॉपी-ऑन-राइट शायद और भी भ्रमित हो जाएगा। यह आपके लिए एक समस्या क्यों है? – Krumelur

+0

@ क्रूमेलर क्योंकि अधिकांश गैर-वैज्ञानिक प्रोग्रामिंग परिदृश्य में, यह इस तरह काम करता है। और मुझे लगता है कि 'matlab' में भी कोई समानता नहीं है।मुझे इस व्यवहार को याद रखना होगा, और मुझे वास्तव में प्रोग्रामिंग में 'पुनरावृत्ति' पसंद नहीं है। – cqcn1991

+0

ठीक है, काफी उचित है। मुझे लगता है कि यह कोड स्लाइसिंग सरणी और कोड करने की स्पष्टता के बीच एक व्यापार-बंद होगा, उदाहरण के लिए 'DoSomething (आगमन [: 6000])'। मुझे लगता है कि मैटलैब इसे हल करने के लिए CoW करता है। – Krumelur

उत्तर

0

What does (numpy) __array_wrap__ do?

ndarray के बारे में उपवर्गों और हुक में बात करती है __array_wrap__ की तरह। np.arraycopy पैरामीटर लेता है, परिणाम के लिए मजबूर कर एक प्रति हो सकता है, भले ही वह अन्य कारणों से आवश्यक नहीं है। ravel एक दृश्य, flatten एक प्रति देता है। इसलिए यह शायद संभव है, और संभवतः ndarray सबक्लास बनाने के लिए बहुत मुश्किल नहीं है जो एक प्रतिलिपि बनाता है। इसमें __array_wrap__ जैसे हुक को संशोधित करना शामिल हो सकता है।

या हो सकता है .__getitem__ विधि को संशोधित। slice_of_arr = arr[0:6] में इंडेक्सिंग में __getitem__ पर कॉल शामिल है। ndarray के लिए यह संकलित किया गया है, लेकिन एक नकाबपोश सरणी के लिए, यह है कि आप एक उदाहरण के रूप इस्तेमाल कर सकते हैं अजगर कोड है:

/usr/lib/python3/dist-packages/numpy/ma/core.py 

यह

def __getitem__(self, indx): 
    """x.__getitem__(y) <==> x[y] 
    """ 
    # _data = ndarray.view(self, ndarray) # change to: 
    _data = ndarray.copy(self, ndarray) 
    dout = ndarray.__getitem__(_data, indx) 
    return dout 

के रूप में सरल कुछ हो सकता है लेकिन मैं से कि संदेह जब आप विकसित होते हैं और इस तरह के उप-वर्ग का पूरी तरह से परीक्षण करते हैं, तो आप डिफ़ॉल्ट नो-कॉपी दृष्टिकोण से प्यार में पड़ सकते हैं। हालांकि यह व्यू-वी-कॉपी व्यवसाय कई नए कॉमर्स काटता है (विशेष रूप से यदि MATLAB से आ रहा है), तो मैंने अनुभवी उपयोगकर्ताओं से शिकायतें नहीं देखी हैं। अन्य numpy SO प्रश्नों को देखो; आपको copy() कॉल नहीं दिखाई देंगे।

यहां तक ​​कि नियमित रूप से अजगर उन इस्तेमाल खुद को पूछ रहे हैं एक संदर्भ या टुकड़ा एक प्रति है या नहीं, और चाहे कुछ परिवर्तनशील है या नहीं।

सूचियों के साथ उदाहरण के लिए

:

In [754]: ll=[1,2,[3,4,5],6] 
In [755]: llslice=ll[1:-1] 
In [756]: llslice[1][1:2]=[10,11,12] 
In [757]: ll 
Out[757]: [1, 2, [3, 10, 11, 12, 5], 6] 

एक आइटम एक टुकड़ा अंदर एक आइटम को संशोधित करने को संशोधित करता है कि मूल सूची में एक ही आइटम। numpy के विपरीत, एक सूची टुकड़ा एक प्रति है। लेकिन यह एक उथली प्रति है। आपको गहरी प्रतिलिपि बनाने के लिए अतिरिक्त प्रयास करना होगा (import copy)।

/usr/lib/python3/dist-packages/numpy/lib/index_tricks.py कुछ अनुक्रमण संचालन और अधिक सुविधाजनक बनाने के उद्देश्य से कुछ अनुक्रमण कार्यों में शामिल है। कस्टम __getitem__ विधियों के साथ कई कक्षाएं, या कक्षा के उदाहरण हैं। वे आपकी स्लाइसिंग और इंडेक्सिंग को कस्टमाइज़ करने के मॉडल के रूप में भी काम कर सकते हैं।

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

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