I need to check if a point lies inside a bounding cuboid. The number of cuboids is very large (~4M). The code I come up with is:
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)
It takes 8 seconds to run np.all
and 3 seconds to run np.nonzero
on my computer. Any idea to speed up the code?
We can reduce memory congestion for all-reduction
with slicing
along the smallest axis length of 3
to get 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])
Timings -
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With