2011-05-11 4 views
6

निम्न numpy कोड पर विचार करें:numpy: बूलियन अनुक्रमण और स्मृति उपयोग

A[start:end] = B[mask] 

यहां:

  • A और B कॉलम की समान संख्या वाले 2 डी सरणी हैं;
  • start और end स्केलर हैं;
  • mask एक 1 डी बुलियन सरणी है;
  • (end - start) == sum(mask)

सिद्धांत रूप में, B के तत्वों को सीधे A में कॉपी करके उपरोक्त ऑपरेशन O(1) अस्थायी संग्रहण का उपयोग करके किया जा सकता है।

क्या यह वास्तव में अभ्यास में होता है, या numpyB[mask] के लिए एक अस्थायी सरणी बनाता है? यदि उत्तरार्द्ध, कथन को फिर से लिखकर इससे बचने का कोई तरीका है?

उत्तर

2

बूलियन सरणियों के रूप में उपयोग सूचकांक फैंसी अनुक्रमण, एक प्रतिलिपि बनाने के लिए इतना numpy की जरूरत है। यदि आप स्मृति समस्याओं को प्राप्त करते हैं, तो आप इससे निपटने के लिए एक साइथन एक्सटेंशन लिख सकते हैं।

+0

+1। यह इस तरह के लूप है कि यह एक्सेल करता है। –

3

लाइन

A[start:end] = B[mask] 

जाएगा - अजगर भाषा परिभाषा के अनुसार - पहले दाहिने हाथ की ओर का मूल्यांकन, B के चयनित पंक्तियों से युक्त और अतिरिक्त मेमोरी कब्जे एक नई सरणी उपज। सबसे कुशल शुद्ध अजगर तरह से मैं के बारे में पता कर रहा हूँ इस से बचने के लिए एक स्पष्ट पाश उपयोग करने के लिए है:

from itertools import izip, compress 
for i, b in izip(range(start, end), compress(B, mask)): 
    A[i] = b 

बेशक यह बहुत कम समय कुशल अपने मूल कोड से हो जाएगा, लेकिन यह केवल हे का उपयोग करता है (1) अतिरिक्त स्मृति। यह भी ध्यान रखें कि itertools.compress() पायथन 2.7 या 3.1 या उससे ऊपर में उपलब्ध है। साइथन में लाने के लिए

+1

निश्चित रूप से, "बी के चयनित पंक्तियों और अतिरिक्त मेमोरी पर कब्जा करने वाली एक नई सरणी उत्पन्न करना" एक गैर अनुक्रमक है? यह 'बी .__ getitem __()' पर निर्भर करता है कि वह क्या लौटना चाहता है। उदाहरण के लिए, यदि 'मास्क' एक 'टुकड़ा' था, तो प्रॉक्सी (दृश्य) वापस कर दिया जाएगा, और कोई प्रति नहीं होगी। – NPE

+0

@aix: ओपी के मुताबिक, 'मास्क' एक-आयामी बूलियन सरणी है। क्या मैं कुछ भूल गया? –

+0

@aix: ओह, मैं देखता हूं। भाषा deifnition के साथ हिस्सा थोड़ा अस्पष्ट है। इसका मतलब केवल "दाएं हाथ की ओर पहला मूल्यांकन" भाग को संदर्भित करना था। –