numpy

2014-04-24 9 views
7

में अद्वितीय तत्वों के समूह को इंडेक्स करना मेरे पास पूर्णांक की कई बड़ी (> 100,000,000) सूचियां हैं जिनमें कई डुप्लिकेट हैं। मैं इंडेक्स प्राप्त करना चाहता हूं जहां प्रत्येक तत्व होता है। वर्तमान में मैं ऐसा कुछ कर रहा हूं:numpy

import numpy as np 
from collections import defaultdict 

a = np.array([1, 2, 6, 4, 2, 3, 2]) 
d=defaultdict(list) 
for i,e in enumerate(a): 
    d[e].append(i) 

d 
defaultdict(<type 'list'>, {1: [0], 2: [1, 4, 6], 3: [5], 4: [3], 6: [2]}) 

प्रत्येक तत्व के माध्यम से पुनरावृत्ति करने की यह विधि समय लेने वाली है। क्या ऐसा करने के लिए कोई कुशल या सदिश तरीका है?

Edit1 मैं Acorbe और जैमे के तरीकों की कोशिश की निम्नलिखित

a = np.random.randint(2000, size=10000000) 

पर परिणाम

original: 5.01767015457 secs 
Acorbe: 6.11163902283 secs 
Jaime: 3.79637312889 secs 
+0

मुझे लगता है कि बहु प्रसंस्करण उर fuction उर problem..https का समाधान होगा: –

उत्तर

3

पर विचार यह बहुत क्या here में पूछा गया था, तो क्या इस प्रकार मेरा उत्तर वहाँ का रूपांतरण है के समान है। इसे सदिश बनाने का सबसे आसान तरीका सॉर्टिंग का उपयोग करना है। निम्नलिखित कोड आगामी संस्करण 1.9, जो अद्वितीय आइटम गिनती कार्यक्षमता भी शामिल है के लिए np.unique के कार्यान्वयन से बहुत कुछ उधार लेता है, here देखें:

>>> a = np.array([1, 2, 6, 4, 2, 3, 2]) 
>>> sort_idx = np.argsort(a) 
>>> a_sorted = a[idx] 
>>> unq_first = np.concatenate(([True], a_sorted[1:] != a_sorted[:-1])) 
>>> unq_items = a_sorted[unq_first] 
>>> unq_count = np.diff(np.nonzero(unq_first)[0]) 

और अब:

>>> unq_items 
array([1, 2, 3, 4, 6]) 
>>> unq_count 
array([1, 3, 1, 1, 1], dtype=int64) 

के लिए स्थितीय सूचकांक प्राप्त करने के लिए प्रत्येक मान, हम बस कार्य करें:

>>> unq_idx = np.split(sort_idx, np.cumsum(unq_count)) 
>>> unq_idx 
[array([0], dtype=int64), array([1, 4, 6], dtype=int64), array([5], dtype=int64), 
array([3], dtype=int64), array([2], dtype=int64)] 

और तुम अब निर्माण कर सकते हैं अपने शब्दकोश ज़िप करने unq_items एक nd unq_idx

ध्यान दें कि unq_count अंतिम अद्वितीय आइटम की घटनाओं की गणना नहीं करता है, क्योंकि इंडेक्स सरणी को विभाजित करने की आवश्यकता नहीं है। यदि आप सभी मूल्यों करना चाहते थे तुम कर सकते हो:

>>> unq_count = np.diff(np.concatenate(np.nonzero(unq_first) + ([a.size],))) 
>>> unq_idx = np.split(sort_idx, np.cumsum(unq_count[:-1])) 
2

इस python pandas (अजगर डेटा विश्लेषण पुस्तकालय) के माध्यम से हल किया जा सकता है और एक कर रहे हैं DataFrame.groupby कॉल करें।

निम्नलिखित

a = np.array([1, 2, 6, 4, 2, 3, 2]) 

import pandas as pd 
df = pd.DataFrame({'a':a}) 

gg = df.groupby(by=df.a) 
gg.groups 

उत्पादन

{1: [0], 2: [1, 4, 6], 3: [5], 4: [3], 6: [2]} 
+0

//docs.python.org/2/library/multiprocessing.html मैं पांडा इस्तेमाल नहीं किया है। क्या यह शुद्ध पायथन संस्करण से तेज़ है। – imsc

+0

@imsc, AFAIK यह डेटा प्रकारों से संबंधित है और गति के लिए साइथन और शुद्ध सी विधियों को लागू करने के लिए numpy पर आधारित है। मैं नियमित रूप से और खुशी से बड़े डेटासेट (~ 10 एम रिकॉर्ड) के लिए इसका उपयोग करता हूं। – Acorbe

+0

धन्यवाद, मैं इसका परीक्षण करूंगा और आपको बता दूंगा। – imsc

2

numpy_indexed पैकेज (अस्वीकरण: मैं उसके लेखक हूँ) एक समाधान जैमे के से प्रेरित लागू करता है; लेकिन परीक्षणों के साथ, एक अच्छा इंटरफेस, और बहुत से संबंधित कार्यक्षमता:

import numpy_indexed as npi 
unique, idx_groups = npi.group_by(a, np.arange(len(a)) 
0

सरल और त्वरित समाधान।

a = np.array([0, 0, 0, 1, 1, 3, 3, 3, 2, 2, 2, 0, 0, 1, 4]) 
sort_idx = np.argsort(a) 
unique, counts = np.unique(a, return_counts=True) 
b = {key: sort_idx[sum(counts[:key]): sum(counts[:key]) + counts[key]] for key in unique} 

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