如何加速numpy.all和numpy.nonzero()函数?

6

我需要检查一个点是否在一个边界立方体内。需要检查的立方体数量非常大(约为4M)。我编写的代码如下:

import numpy as np

# set the numbers of points and cuboids
n_points = 64
n_cuboid = 4000000

# generate the test data
points = np.random.rand(1, 3, n_points)*512
cuboid_min = np.random.rand(n_cuboid, 3, 1)*512
cuboid_max = cuboid_min + np.random.rand(n_cuboid, 3, 1)*8

# main body: check if the points are inside the cuboids
inside_cuboid = np.all((points > cuboid_min) & (points < cuboid_max), axis=1)
indices = np.nonzero(inside_cuboid)

在我的电脑上,运行np.all需要8秒钟,而运行np.nonzero只需要3秒钟。有什么方法可以加速代码吗?

1个回答

3
我们可以通过沿着长度为3的最小轴切分来减少all-reduction 的内存拥塞,以获得inside_cuboid
out = (points[0,0,:] > cuboid_min[:,0]) & (points[0,0,:] < cuboid_max[:,0]) & \
      (points[0,1,:] > cuboid_min[:,1]) & (points[0,1,:] < cuboid_max[:,1]) & \
      (points[0,2,:] > cuboid_min[:,2]) & (points[0,2,:] < cuboid_max[:,2])

时间 -

In [43]: %timeit np.all((points > cuboid_min) & (points < cuboid_max), axis=1)
2.49 s ± 20 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [51]: %%timeit
    ...: out = (points[0,0,:] > cuboid_min[:,0]) & (points[0,0,:] < cuboid_max[:,0]) & \
    ...:       (points[0,1,:] > cuboid_min[:,1]) & (points[0,1,:] < cuboid_max[:,1]) & \
    ...:       (points[0,2,:] > cuboid_min[:,2]) & (points[0,2,:] < cuboid_max[:,2])
1.95 s ± 10.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

谢谢。这很有帮助!它在我的电脑上节省了60%的时间。但我需要让它至少快10倍。还有其他想法吗? - f. c.
@f.c. 鉴于您的特定要求需要10倍加速,对于您来说提供奖金可能是公平的,这样我们所有人都将获得额外的动力和更多的关注。 - Divakar
我已经转向另一种解决方案以使其更快。请查看我的新帖子 https://stackoverflow.com/questions/64043572/how-to-speed-up-an-n-dimensional-interval-tree-in-python。如果需要,将为该问题添加赏金。 - f. c.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接