Numpy意味着有条件

时间:2012-06-18 14:13:13

标签: python numpy

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

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

5 个答案:

答案 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)