我有纯蟒蛇计算平均速度的算法:
speed = [...]
avg_speed = 0.0
speed_count = 0
for i in speed:
if i > 0: # I dont need zeros
avg_speed += i
speed_count += 1
if speed_count == 0:
return 0.0
return avg_speed / speed_count
有没有办法用Numpy重写这个函数?
答案 0 :(得分:21)
函数numpy.average
可以接收一个weights
参数,在这个参数中你可以将一些条件生成的布尔数组应用于数组本身 - 在这种情况下,一个元素大于0:
average_speed = numpy.average(speeds, weights=(speeds > 0))
希望这有帮助
答案 1 :(得分:15)
我很惊讶没有人提出最短的解决方案:
speeds_np = np.array(speeds)
speeds_np[speeds_np>0].mean()
<强>解释强>
speedsNp > 0
创建一个大小相同的布尔数组,满足(in)相等性。如果输入speedsNp
,它只产生speedNp
的相应值,其中布尔数组的值为True
。您需要做的就是获取结果的mean()
。
答案 2 :(得分:10)
import numpy as np
def avg_positive_speed(speed):
s = np.array(speed)
positives = s > 0
if positives.any():
return s[positives].mean()
else:
return 0.
speed = [1., 2., 0., 3.]
print avg_positive_speed(speed)
# prints 2.0
print avg_positive_speed([0., 0.])
# prints 0.0
答案 3 :(得分:3)
我知道你想要一个numpy
解决方案,所以这不符合这个标准(@ eumiro的早期帖子肯定会这样做),但作为替代方案,这里是一个优化的Python版本,令人惊讶(至少对我来说) )结果很快!
speeds = [i for i in speed if i > 0]
return sum(speeds) / (1.0 * len(speeds)) if sum(speeds) > 0 else 0.0
可能有趣的是将它与速度方面的numpy(或原始)实现进行比较。
In [14]: timeit original(speed) # original code
1000 loops, best of 3: 1.13 ms per loop
In [15]: timeit python_opt(speed) # above Python 2 liner
1000 loops, best of 3: 582 us per loop
In [16]: timeit avg_positive_speed(speed) # numpy code
1000 loops, best of 3: 1.2 ms per loop
其中
speed = range(10000)
我原以为numpy
会有优势......任何人都知道它为什么会落后?
更新
speed = range(100000)
:
In [19]: timeit original(speed)
100 loops, best of 3: 12.2 ms per loop
In [20]: timeit python_opt(speed)
100 loops, best of 3: 11 ms per loop
In [21]: timeit avg_positive_speed(speed)
100 loops, best of 3: 12.5 ms per loop
仍然不相信numpy
是 此 特定问题的好工具,除非巨大数量的速度:)
numpy如何处理内存?列表理解会在某些时候遇到一些限制。
答案 4 :(得分:0)
从 v1.20 起,numpy 的 mean
等函数支持 where
参数:
speed.mean(where=speed>0)