将点云划分为python中的象限

时间:2015-05-21 16:29:08

标签: python arrays numpy

假设我在3个维度中有一个30个点的数组,在python中被转换为numpy数组:

import numpy as np
b = np.round(np.random.random((30,3))*20)
b = b - b.mean(axis=0)

我想把这些点分成8个象限,参考"质量中心"点云。我可以这样做:

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

当然,这很好用。它返回一个包含八个位置坐标数组的列表,每个位置坐标只包含特定象限中的点。但是我觉得应该有更清晰,更简洁的方法来处理这个问题。建议?

2 个答案:

答案 0 :(得分:3)

这是一个递归解决方案。它应该适用于任意数量的维度。

public static class ColorBar
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
    public enum Color { None, Green, Red, Yellow }

    public static void SetState(this ProgressBar pBar, Color newColor, int newValue)
    {
        if (pBar.Value == pBar.Minimum)  // If it has not been painted yet, paint the whole thing using defualt color...
        {                                // Max move is instant and this keeps the initial move from going out slowly 
            pBar.Value = pBar.Maximum;   // in wrong color on first painting
            SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
        }
        pBar.Value = newValue;
        SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);     // run it out to the correct spot in default
        SendMessage(pBar.Handle, 1040, (IntPtr)(int)newColor, IntPtr.Zero);        // now turn it the correct color
    }

}

答案 1 :(得分:0)

对于大型数组,递归的计算量可能太大。

一个更好的选择可能是一个函数,它可以返回点本身分为四部分,或者只返回四分之一的索引而不递归(仍然应该适用于任意数量的维度)。

import numpy as np

def split_into_quadrants(points, get_quadrants_index=False):
   ndims = points.shape[1]
   existing_quadrants = list(itertools.product([-1, 1], repeat=ndims))
   quadrants_dict = dict(zip(existing_quadrants,range(len(existing_quadrants))))
   sign_points = np.sign(points)
   quadrants_idx = np.apply_along_axis(lambda x: quadrants_dict[(tuple(x.astype(int)))], 1, sign_points)
   if get_quadrants_index:
       return quadrants_idx
   points_split_into_quadrants = []
   for i in set(quadrants_idx):
       points_split_into_quadrants.append(points[quadrants_idx==i])
   return points_split_into_quadrants

b = np.round(np.random.random((30,3))*20)
b = b - b.mean(axis=0)
print(split_into_quadrants(b,get_quadrants_index=False))