Dividing point clouds into quadrants in python
Suppose I have an array of 30 points in 3 dimensions, selected as a numpy array in python:
import numpy as np b = np.round(np.random.random((30,3))*20) b = b - b.mean(axis=0)
I want to divide these points into eight quadrants with reference to the "center of mass" of the point cloud. I could do something like this:
for a in (b, -b):
q_list = a[a[:,0]>0.][a[a[:,0]>0.][:,1]>0][a[a[:,0]>0.][a[a[:,0]>0.][:,1]>0][:,2]>0]
quad_list.append(q_list * sign)
q_list = a[a[:,0]>0.][a[a[:,0]>0.][:,1]>0][a[a[:,0]>0.][a[a[:,0]>0.][:,1]>0][:,2]<=0]
quad_list.append(q_list * sign)
q_list = a[a[:,0]>0.][a[a[:,0]>0.][:,1]<=0][a[a[:,0]>0.][a[a[:,0]>0.][:,1]<=0][:,2]>0]
quad_list.append(q_list * sign)
q_list = a[a[:,0]>0.][a[a[:,0]>0.][:,1]<=0][a[a[:,0]>0.][a[a[:,0]>0.][:,1]<=0][:,2]<=0]
quad_list.append(q_list * sign)
sign *= -1
This works great, of course. It returns a list with eight arrays of position coordinates, each containing only points that lie in a specific quadrant. However, I feel like there should be a clearer, more concise way to handle this. Suggestions?
+3
source to share
1 answer
Here's a recursive solution. It should work for an arbitrary number of dimensions.
import numpy as np
def split_into_quadrants(points, idx=0):
if idx < points.shape[-1]:
positive = points[points[:, idx] >= 0]
negative = points[points[:, idx] < 0]
return (split_into_quadrants(positive, idx+1) +
split_into_quadrants(negative, idx+1))
else:
return [points]
b = np.round(np.random.random((30,3))*20)
b = b - b.mean(axis=0)
print(split_into_quadrants(b))
+3
source to share