优化更快的numpy'其中'布尔条件

时间:2018-01-28 15:57:34

标签: python-3.x numpy

我使用

生成一堆5元素向量
def beam(n):
    # For performance considerations, see
    # https://software.intel.com/en-us/blogs/2016/06/15/faster-random-number-generation-in-intel-distribution-for-python
    try:
        import numpy.random_intel
        generator = numpy.random_intel.multivariate_normal
    except ModuleNotFoundError:
        import numpy.random
        generator = numpy.random.multivariate_normal
    return generator(
        [0.0,
         0.0,
         0.0,
         0.0,
         0.0
         ],
        numpy.array([
            [1.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.2]
        ]),
        int(n)
    )

此向量将乘以5x5矩阵(元素方式)并检查边界。我用这个:

 b = beam(1e5)
 bound = 1000
 s = (b[:, 0]**2 + b[:, 3]**2) < bound**2
 #b[np.where(s)] (equivalent performances)
 b[s] # <= returned value from a function

看起来这个100k元素的操作非常耗时(我的机器上有3ms)。

  

是否有明显(或不那么明显)的方式来执行此操作   操作(where部分,随机生成是为了给出一个例子)?

1 个答案:

答案 0 :(得分:0)

由于你的组件是不相关的,一个明显的加速是使用单变量正常而不是多变量:

>>> from timeit import repeat
>>> import numpy as np
>>> 
>>> kwds = dict(globals=globals(), number=100)
>>> 
>>> repeat('np.random.multivariate_normal(np.zeros((5,)), np.diag((1,1,1,1,0.2)), (100,))', **kwds)
[0.01475344318896532, 0.01471381587907672, 0.013099645031616092]
>>> repeat('np.random.normal((0,0,0,0,0), (1,1,1,1,np.sqrt(0.2)), (100, 5))', **kwds)
[0.003930734936147928, 0.004097769036889076, 0.004246715921908617]

此外,目前您的情况极不可能失败。因此,只需检查s.all()以及True是否无效。