2016-05-26 10 views
5

मैं इस तरह केNumpy एक और सरणी में तत्व सूचकांक खोजने

>>> A = np.random.choice(unique, 100) 

के रूप में एक सरणी/अद्वितीय धनात्मक पूर्णांक के साथ सेट, यानी

>>> unique = np.unique(np.random.choice(100, 4, replace=False)) 

और एक सरणी यह ​​पिछले सरणी से नमूना कई तत्वों से युक्त, मैं सरणी A के मानों को मैप करना चाहता हूं, जिनकी स्थिति unique में होती है।

अब तक का सबसे अच्छा समाधान मैंने पाया एक मानचित्रण सरणी के माध्यम से है:

>>> table = np.zeros(unique.max()+1, unique.dtype) 
>>> table[unique] = np.arange(unique.size) 

प्रत्येक तत्व सरणी पर सूचकांक, और इस तरह, बाद में इस्तेमाल किया जा सकता उन्नत अनुक्रमण के माध्यम से A मैप करने के लिए करने के लिए ऊपर प्रदान करती है:

>>> table[A] 
array([2, 2, 3, 3, 3, 3, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0, 
     0, 3, 3, 2, 1, 0, 0, 0, 2, 1, 0, 3, 0, 1, 3, 0, 1, 2, 3, 3, 3, 3, 1, 
     3, 0, 1, 2, 0, 0, 2, 3, 1, 0, 3, 2, 3, 3, 3, 1, 1, 2, 0, 0, 2, 0, 2, 
     3, 1, 1, 3, 3, 2, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 
     3, 2, 2, 1, 3, 0, 3, 3], dtype=int32) 

जो मुझे पहले से ही उचित समाधान देता है। हालांकि, यदि unique में अद्वितीय संख्याएं बहुत ही कम और बड़ी हैं, तो इस दृष्टिकोण का अर्थ है कि बाद में मैपिंग के लिए कुछ संख्याओं को स्टोर करने के लिए बहुत बड़ी table सरणी बनाना।

क्या कोई बेहतर समाधान है?

नोट: A और unique दोनों नमूना सरणी हैं, वास्तविक सरणी नहीं हैं। तो सवाल यह नहीं है कि कैसे स्थितीय अनुक्रमित उत्पन्न करने के लिए है, यह है बस कैसे कुशलतापूर्वक, unique में अनुक्रमित करने के लिए A के तत्वों को मैप करने, मैं numpy में इस प्रकार है speedup करना चाहते हैं की स्यूडोकोड

B = np.zeros_like(A) 
for i in range(A.size): 
    B[i] = unique.index(A[i]) 

(माना जाता है कि unique उपरोक्त छद्म कोड) में एक सूची है।

उत्तर

4

साथ तालिका दृष्टिकोण अपने प्रश्न में वर्णन किया गया सबसे अच्छा विकल्प का उपयोग कर सकते हैं जब unique अगर बहुत घने, लेकिन unique.searchsorted(A) एक ही परिणाम का उत्पादन करना चाहिए और करने के लिए unique की आवश्यकता नहीं है घना होना searchsorted इनट्स के साथ बहुत बढ़िया है, अगर कोई इस तरह की चीज को फ्लोट्स के साथ करने की कोशिश कर रहा है जिसमें सटीक सीमाएं हैं, तो this जैसे कुछ पर विचार करें।

+0

और 'सॉर्टर' का उपयोग इसके साथ किया जा सकता है, अगर 'अद्वितीय' पहले से सॉर्ट नहीं किया गया है। – Divakar

1

आप मानक अजगर dictnp.vectorize

inds = {e:i for i, e in enumerate(unique)} 
B = np.vectorize(inds.get)(A) 
+0

दिलचस्प दृष्टिकोण, हालांकि मुझे बड़ी matrices के लिए 'np.vectorize' के प्रदर्शन का परीक्षण करना होगा। –

+0

पायथन स्तर पर np.vectorize loops, इसलिए उस परीक्षण को करने की कोई ज़रूरत नहीं है ... इसकी सिंटैक्टिक चीनी –

2

numpy_indexed पैकेज (अस्वीकरण: मैं उसके लेखक हूँ):

import numpy_indexed as npi 
npi.indices(unique, A) 

list.index के एक vectorized बराबर है, जो स्मृति अधिकतम तत्व के लिए आनुपातिक है, लेकिन केवल इनपुट खुद के लिए आनुपातिक की आवश्यकता नहीं है शामिल ध्यान दें कि यह मनमाने ढंग से dtypes और आयामों के लिए भी काम करता है। इसके अलावा, पूछे जाने वाले सरणी को अद्वितीय होने की आवश्यकता नहीं है; सामने आने वाली पहली अनुक्रमणिका वापस लौटा दी जाएगी, सूची के समान ही।

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