Python:实现逐元素向量相乘的最高效方法
我需要一个函数聚合器,它可以把两个列表合并成一个总数。'Items' 应该是一个布尔值的向量。
所以,我写了这些函数:
def element_wise_multiplication(weights, items):
return map(lambda x, y: x * y, weights, items)
def total(weights, items):
return sum(element_wise_multiplication(weights, items))
我觉得它们看起来还不错,但问题是性能分析工具显示,包含 lambda 的那一行占用了95%的运行时间,所以它的性能实在是太差了。
有没有更高效的实现方法?
附注:我知道 NumPy 的数组,但我想在这个情况下使用 PyPy。或者说在这种情况下使用它不值得吗?
3 个回答
1
试试这个:
def total(weights, items):
return sum (x * y for x, y in zip(weights, items))
2
虽然你提到不想在这种情况下使用numpy,但看看速度差异可能还是值得的。
最好的非numpy解决方案似乎是使用izip的生成器,它的性能稍微好于zip。
In [31]: %timeit sum(x*y for x,y in zip(weights,items))
10000 loops, best of 3: 158 us per loop
In [32]: %timeit sum(x*y for x,y in izip(weights,items))
10000 loops, best of 3: 125 us per loop
但是当我们使用numpy数组时,我们会得到:
In [33]: %timeit (np_weights,np_items).sum()
100000 loops, best of 3: 9.08 us per loop
使用numpy的方案快了整整14倍。如果这真的是你代码中的瓶颈,那么使用numpy就是最好的选择。
3
你可以用一个生成器来解决这个问题,方法如下:
from itertools import izip
value = sum((x * y) for x, y in izip(weights, items))
izip
的功能和内置的zip
是一样的,但它不会占用太多内存。