2016-08-08 92 views
0

我需要創建一組消息的ID和原始列表中的位置。該代碼用於根據ID稍後對消息進行排序。創建集合並在集合中有效位置列表

以下的工作,是可讀的,但速度慢。

import numpy as np 
IDs=np.array([354,45,45,34,354])#example, the actual array is huge 

Dict={} 
for counter in xrange(len(IDs)): 
    try: 
     Dict[IDs[counter]].append(counter) 
    except: 
     Dict[IDs[counter]]=[counter] 
print(Dict) 
#{354: [0, 4], 34: [3], 45: [1, 2]} 

任何想法如何加快它?沒有必要對列表進行排序。在後面的代碼如下使用,之後的字典被丟棄

for item in Dict.values(): 
    Position_of_ID=Position[np.array(item)] 
    ... 

回答

0

Mutch快使用「dictcompression」

Dict = {id:i for i, id in enumerate(IDs)} 
1

嘗試使用defaultdictenumerate

from collections import defaultdict  
Dict = defaultdict(list) 
for i,id in enumerate(IDs): 
    Dict[id].append(i) 

(使用tryexcept是一個壞主意if the exceptions aren't rare

+1

與我的數據,節省了大約三分之一的執行時間,美觀大方。 – Okapi575

+0

但是,仍然必須有一種方法做到這一點,沒有純粹的Python循環,並可能沒有使用字典。 – Okapi575

0

我想出的最快的代碼是這個。它還能做得更多的數學,是不是爲可讀,我不感到自豪,但它是快了很多(即使有大型排列):

Sorted_positions_of_IDs=np.argsort(IDs,kind='mergesort') 
    SortedIDs=IDs[Sorted_positions_of_IDs] 
    Position=0  
    Position_last=-1 
    Dict={} 
    while(Position<len(Sorted_positions_of_IDs)): 
     ID=SortedIDs[Position] 
     Position_last=np.searchsorted(SortedIDs,ID,side='right') 
     Dict[ID]=Sorted_positions_of_IDs[Position:Position_last] 
     Position=Position_last 

無論如何,好的想法可以理解的。