【问题标题】:Create set and lists with the positions in the set efficently有效地使用集合中的位置创建集合和列表
【发布时间】:2016-08-08 10:08:04
【问题描述】:

我需要创建一组消息的 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]}

任何想法如何加快它?不需要对列表进行排序。后面的代码使用如下,然后dict就被丢弃了

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

【问题讨论】:

    标签: python dictionary


    【解决方案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

    【讨论】:

    • 我的数据可以节省大约三分之一的执行时间,很好。
    • 但是仍然必须有一种方法可以在没有纯 python 循环的情况下执行此操作,并且可能不使用 dicts。
    【解决方案2】:

    我想出的最快的代码就是这个。它做了更多的数学运算,不那么可读,我并不自豪,但它要快得多(即使是大型数组):

        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
    

    无论如何,好的想法都会受到赞赏。

    【讨论】:

      【解决方案3】:

      Mutch faster 正在使用“字典压缩”

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-20
        相关资源
        最近更新 更多