11

我有计算纯python平均速度的算法:

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 重写这个函数?

4

5 回答 5

28

该函数numpy.average可以接收一个weights参数,您可以在其中放置一个从应用于数组本身的某些条件生成的布尔数组 - 在这种情况下,一个大于 0 的元素:

average_speed = numpy.average(speeds, weights=(speeds > 0))

希望这可以帮助

于 2012-06-18T14:45:41.217 回答
27

我很惊讶没有人提出最短的解决方案:

speeds_np = np.array(speeds)

speeds_np[speeds_np>0].mean()

解释:

speedsNp > 0创建一个大小相同的布尔数组,满足(不)等式。如果输入speedsNp,它只产生speedNp布尔数组的值所在的对应值True。然后,您需要做的就是获取mean()结果。

于 2015-07-09T08:41:07.907 回答
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
于 2012-06-18T14:14:41.603 回答
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 如何处理内存?列表理解在某些时候会遇到一些限制。

于 2012-06-18T14:16:14.027 回答
2

v1.20开始, numpy 的meanetc 函数支持一个where参数:

speed.mean(where=speed>0)
于 2021-03-24T22:43:30.407 回答