python - 有没有办法进一步优化Python的heapq.nlargest来选择前N个项目?

标签 python performance optimization profiling heap

我使用 heapq.nlargest 选择前 N 个项目,它占用了 98% 的运行时间(参见第 51 行):

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
40                                           @profile
41                                           def gen_submit(index_to_pri, index_to_sec, exclude_set, pri_mat, sec_mat, gen_count):
42         1           33     33.0      0.0      print('gen_submit')
43         1           87     87.0      0.0      f = open('../submission.txt', 'w')
44        16           28      1.8      0.0      for i, pri in enumerate(index_to_pri):
45        16          369     23.1      0.0          print('generate recommendation for %d-th primary object' % i)
46        16          103      6.4      0.0          recommend_sec = []
47        16           25      1.6      0.0          exclude = exclude_set[pri]
48        16        68215   4263.4      1.3          rating_vector = numpy.dot(pri_mat[i], sec_mat.T)
49                                                   # extract top N
50        16          102      6.4      0.0          N = 500 + len(exclude_set[pri])
51        16      4988735 311795.9     98.2          top_N_indexed_rating = heapq.nlargest(N, enumerate(rating_vector), key = lambda x: x[1]))
52        15          181     12.1      0.0          top_N_j = map(lambda x: x[0], top_N_indexed_rating)
53      7501         6229      0.8      0.1          for j in top_N_j:
54      7501         4812      0.6      0.1              if not index_to_sec[j] in exclude:
55      7500         6135      0.8      0.1                  recommend_sec.append(str(j))
56      7500         4943      0.7      0.1                  if len(recommend_sec) >= 500: break
57        15          293     19.5      0.0          f.write(' '.join(recommend_sec) + '\n')
58                                               f.close()

我如何进一步优化这个单一操作?

最佳答案

新答案

如果您不需要在 top_N_j 内订购,请尝试

top_N_j = rating_vector.argpartition(len(rating_vector) - N)[-N:]

否则稍后排序

top_N_j = top_N_j[numpy.argsort(rating_vector[top_N_j])]

我认为这比您所花费的时间大约少了 30 到 50 倍。

<小时/>

旧答案

我想这太明显了,我可能完全没有捕获重点,但是

heapq.nlargest(N, enumerate(...))

只会以相反的顺序获取最后的N 元素,并按其索引进行标记。然后您仅将其用于

top_N_j = map(lambda x: x[0], top_N_indexed_rating)

这会将其单独转换为索引。

看来你想要的是

end = len(...)
start = max(0, end - N)
top_N_j = reversed(range(start, end))

(尽管我必须承认对你所做的事情非常感到困惑。)

关于python - 有没有办法进一步优化Python的heapq.nlargest来选择前N个项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34973925/

相关文章:

performance - 为什么我的 Ionic CLI 命令比 Cordova 慢很多?

javascript - 评级明星列表的好关键 Prop

python - 导入错误:无法导入名称 'google'

javascript - HTML 性能 (Asp.Net)

python - 比较因子变量每个级别的数据帧的两个连续行的值 - Python Pandas

performance - 当您想发送匿名函数时,执行 (Runnable & Serialized) 是否太昂贵?

excel vba内存使用优化

php - Drupal 是否解析未使用的 Hook ?

python - 找出Python对象的创建位置

python - 如何从Python数据框中的DateTimeIndex中删除微秒?