सुन्न सरणी पर देखें?


90

मेरे पास एक 2D numpyसरणी है। क्या इस पर एक दृश्य बनाने का एक तरीका है जिसमें पहली kपंक्तियाँ और सभी कॉलम शामिल होंगे?

बिंदु अंतर्निहित डेटा की प्रतिलिपि बनाने से बचने के लिए है (सरणी इतनी बड़ी है कि आंशिक प्रतियां बनाना संभव नहीं है।)

जवाबों:


226

ज़रूर, बस इसे इंडेक्स करें जैसा कि आप सामान्य रूप से करेंगे। उदा। y = x[:k, :] यह मूल सरणी में एक दृश्य लौटाएगा। कोई भी डेटा कॉपी नहीं किया जाएगा, और इसके विपरीत किए गए किसी भी अपडेट को yप्रतिबिंबित किया जाएगा x


संपादित करें:

मैं आमतौर पर uint8 के> 10GB 3D सरणियों के साथ काम करता हूं, इसलिए मुझे इस बारे में बहुत चिंता है ... यदि आप कुछ चीजों को ध्यान में रखते हैं, तो Numpy स्मृति प्रबंधन में बहुत कुशल हो सकता है। यहाँ स्मृति में सरणियों की प्रतियां बनाने से बचने के कुछ सुझाव दिए गए हैं:

का प्रयोग करें +=, -=, *=, आदि सरणी की एक प्रतिलिपि बनाने से बचने के। उदाहरण के लिए x += 10, जगह में सरणी को संशोधित करेगा, जबकि x = x + 10एक प्रतिलिपि बनाएगा और इसे संशोधित करेगा। (भी, एक नज़र numexpr पर )

यदि आप के साथ एक प्रति बनाना चाहते हैं , तो पहले से ही नहीं था, तो एक अस्थायी बिंदु सरणी के लिए स्वचालित रूप से अप-कास्ट करने का कारण होगा x = x + 10कि अवगत रहें। हालांकि, जहां एक पूर्णांक सरणी है, इसके बजाय सरणी के रूप में एक ही सटीकता के एक int के लिए डाउन-कास्ट किया जाएगा। x = x + 10.0xx += 10.0x10.0

इसके अतिरिक्त, कई संख्यात्मक कार्य एक outपैरामीटर लेते हैं , जिससे आप इन-प्लेस np.abs(x, x)के निरपेक्ष मूल्य को लेना पसंद कर सकते हैं x


एक दूसरे को संपादित के रूप में, यहाँ पर कुछ और सुझाव है विचारों बनाम प्रतियां NumPy सरणी के साथ:

अजगर सूची के विपरीत, y = x[:]एक प्रति वापस नहीं करता है, यह एक दृश्य लौटाता है। यदि आप एक प्रति चाहते हैं (जो निश्चित रूप से, आपके द्वारा उपयोग की जाने वाली मेमोरी की मात्रा को दोगुना कर देगा) का उपयोग करेंy = x.copy()

आप अक्सर सुन्न सरणियों के "फैंसी इंडेक्सिंग" के बारे में सुनेंगे। सूचकांक के रूप में एक सूची (या पूर्णांक सरणी) का उपयोग करना "फैंसी इंडेक्सिंग" है। यह बहुत उपयोगी हो सकता है, लेकिन डेटा की प्रतिलिपि बनाता है।

इसके एक उदाहरण के रूप में: y = x[[0, 1, 2], :]एक प्रति लौटाता है, जबकि y = x[:3,:]एक दृश्य लौटाएगा।

यहां तक ​​कि वास्तव में क्रेज़ी इंडेक्सिंग x[4:100:5, :-10:-1, None]"सामान्य" इंडेक्सिंग है और यह एक दृश्य लौटाएगा, हालांकि, बड़े सरणियों पर सभी प्रकार के स्लाइसिंग ट्रिक्स का उपयोग करने से डरो मत।

x.astype(<dtype>)नए प्रकार के रूप में डेटा की एक प्रति लौटाएगा, जबकि x.view(<dtype>)एक दृश्य लौटाएगा।

इसके साथ सावधान रहें, हालांकि ... यह बहुत शक्तिशाली और उपयोगी है, लेकिन आपको यह समझने की आवश्यकता है कि अंतर्निहित डेटा को मेमोरी में कैसे संग्रहीत किया जाता है। यदि आपके पास फ़्लोट्स की एक सरणी है, और उन्हें ints के रूप में देखें, (या इसके विपरीत) numpy इनट्स के रूप में सरणी के अंतर्निहित बिट्स की व्याख्या करेंगे।

उदाहरण के लिए, इसका मतलब है कि 1.064-बिट फ्लोट पर एक 64-बिट फ्लोट सिस्टम के 4607182418800017408रूप में देखा जाएगा , और [ 0, 0, 0, 0, 0, 0, 240, 63]अगर uint8 के रूप में देखा जाए तो यह एक सरणी है । यह वास्तव में अच्छा है जब आपको बड़े सरणियों पर किसी प्रकार का बिट-ट्विडलिंग करने की आवश्यकता होती है, हालांकि ... आपके पास निम्न स्तर का नियंत्रण है कि मेमोरी बफर की व्याख्या कैसे की जाती है।


बहुत अच्छी युक्तियों के लिए धन्यवाद! मैं Numpy उपयोगकर्ता गाइड पढ़ रहा था और भ्रमित क्यों x[np.array([1, 1, 3, 1])] += 1संशोधित किया गया था x। अब समझ गया!
tnq177 ४

अच्छा सुझाव! मेरा एक और प्रश्न है। यह साबित करने के लिए कि सुन्न एक प्रतिलिपि को ट्रिगर नहीं करता है, लेकिन सिर्फ एक दृश्य है? अजगर की आईडी () इस बारे में असमर्थ लगती है।
वुहाची

3
@wuhaochi यदि bएक दृश्य है a, तो b.base is aहोगा True। एक प्रति (किसी भी सरणी की) हमेशा होगीarr_copy.base is None
जुआर मर्लिन स्पाक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.