提高此python函数的性能 def按上下文(自身、标签、上下文)划分: #按上下文划分标签 断言len(标签)=len(上下文) by_context=collections.defaultdict(列表) 对于i,枚举中的标签(标签): 按上下文[contexts[i]]。追加(标签) #现在移除所有没有足够样本的 按键\u至\u移除=[] 对于键,按上下文中的值。iteritems(): 如果len(value)

提高此python函数的性能 def按上下文(自身、标签、上下文)划分: #按上下文划分标签 断言len(标签)=len(上下文) by_context=collections.defaultdict(列表) 对于i,枚举中的标签(标签): 按上下文[contexts[i]]。追加(标签) #现在移除所有没有足够样本的 按键\u至\u移除=[] 对于键,按上下文中的值。iteritems(): 如果len(value),python,performance,numpy,Python,Performance,Numpy,此函数的作用是按上下文值划分标签中的值。最后,如果标签计数太低,请删除字典条目 因此,如果所有上下文值都相同,则返回值将是一个具有单个条目的字典,key=context,value=list of all label 若有N个不同的上下文值,返回值将有N个键(每个上下文一个键),每个键的值将是与特定上下文关联的标签列表。列表中标签的顺序并不重要 此函数使用不同的参数调用了数百万次。我已经确定这是使用的瓶颈。大部分开销都在第一个for循环中的list append()调用中 谢谢 尝试更换 def

此函数的作用是按上下文值划分标签中的值。最后,如果标签计数太低,请删除字典条目

因此,如果所有上下文值都相同,则返回值将是一个具有单个条目的字典,key=context,value=list of all label

若有N个不同的上下文值,返回值将有N个键(每个上下文一个键),每个键的值将是与特定上下文关联的标签列表。列表中标签的顺序并不重要

此函数使用不同的参数调用了数百万次。我已经确定这是使用的瓶颈。大部分开销都在第一个for循环中的list append()调用中

谢谢

尝试更换

def _partition_by_context(self, labels, contexts):
    # partition the labels by context
    assert len(labels) == len(contexts)
    by_context = collections.defaultdict(list)
    for i, label in enumerate(labels):
        by_context[contexts[i]].append(label)

    # now remove any that don't have enough samples
    keys_to_remove = []
    for key, value in by_context.iteritems():
        if len(value) < self._min_samples_context:
            keys_to_remove.append(key)
    for key in keys_to_remove:
        del by_context[key]

    return by_context

不要使用
键来删除
,而是尝试

for context, label in zip(contexts, labels):
    by_context[context].append(label)

看起来这两个阵列可以作为一个很好的测试用例:

n = self._min_samples_context
return {c:ls for c,ls in by_context.items() if len(ls) >= n}
使用这些阵列,@Hugh的提升速度提高约10%


我处理其他问题的经验表明,
defaultdict
是收集类似值的非常好的方法。唯一可能更快的方法是将其转换为某种
numpy
索引问题。

由于您只对标签的数量感兴趣,因此此问题更适合,请尝试使用带int的defaultdict,而不是list,只需递增而不是追加。@jpkotta:我不仅对每个上下文的标签数量感兴趣。我需要每个上下文的所有标签,这样我就可以计算每个上下文标签的平均值和stdev。对于长度为100的
标签,您的两个更改将速度提高约10%。谢谢。我会投票赞成你的答案,但我没有足够的声誉!我更像是SO上的潜伏者,而不是推销员收藏家。:)
n = self._min_samples_context
return {c:ls for c,ls in by_context.items() if len(ls) >= n}
N = 100
labels=np.arange(N)
contexts=np.random.randint(0,len(labels)/10,len(labels))