【问题标题】:Faster code to create an Index with Dict使用 Dict 创建索引的更快代码
【发布时间】:2013-12-06 18:28:51
【问题描述】:

我有一个 np 数组 trainY 的元组。每个元组都是一组标签:

array([('php', 'image-processing', 'file-upload', 'upload', 'mime-types'),
       ('firefox',), 
       ('r', 'matlab', 'machine-learning'),
       ('c#', 'url', 'encoding'), 
       ('php', 'api', 'file-get-contents'),
       ('proxy', 'active-directory', 'jmeter'), 
       ('core-plot',),
       ('c#', 'asp.net', 'windows-phone-7'),
       ('.net', 'javascript', 'code-generation'),
       ('sql', 'variables', 'parameters', 'procedure', 'calls')], dtype=object)

我想创建一个用作索引的 Dict 对象。键将是标签,值将是一个列表,其中包含每个键出现的行号:

例如;

键:值

'php': {[0,4]}

我目前的代码是:

label_index = {}
for i, labels in enumerate(trainY):
    for label in labels:
        if label in label_index.keys():
            label_index[label].append(i)
        else:
            label_index[label] = [i]

是否有更快(可能是矢量化)的方式来编写代码?

谢谢!

【问题讨论】:

    标签: python dictionary indexing


    【解决方案1】:

    使用collections.defaultdict

    >>> a = np.array([('php', 'image-processing', 'file-upload', 'upload', 'mime-types'),
           ('firefox',), 
           ('r', 'matlab', 'machine-learning'),
           ('c#', 'url', 'encoding'), 
           ('php', 'api', 'file-get-contents'),
           ('proxy', 'active-directory', 'jmeter'), 
           ('core-plot',),
           ('c#', 'asp.net', 'windows-phone-7'),
           ('.net', 'javascript', 'code-generation'),
           ('sql', 'variables', 'parameters', 'procedure', 'calls')], dtype=object)
    
    >>> from collections import defaultdict
    >>> d = defaultdict(list)
    >>> for i, x in enumerate(a):
    ...     for k in x:
    ...         d[k].append(i)
    ...         
    >>> d['php']
    [0, 4]
    

    【讨论】:

    • 值得注意的是,尽管这使代码更好,但它的运行时间与@gnibbler 的答案几乎相同。 (但我没有看到任何方法可以使实际操作更快,而不是使用 Cython/C。)
    • defaultdict 太棒了,从来不知道。我什么时候应该使用普通的dict?曾经吗?
    【解决方案2】:

    在 Python2 中,dict.keys() 返回一个列表,因此除了创建一个不必要的列表之外,它还将 O(1) 查找变成了线性扫描

    label_index = {}
    for i, labels in enumerate(trainY):
        for label in labels:
            if label in label_index:
                label_index[label].append(i)
            else:
                label_index[label] = [i]
    

    【讨论】:

    • 很好的答案,谢谢。我的代码昨晚没有完成,但随着您的更改,它在 defaultdict)。
    猜你喜欢
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 2015-02-25
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    相关资源
    最近更新 更多