如何在python中确定数组中连接线的集合

时间:2012-07-18 14:41:24

标签: python numpy nearest-neighbor

我有一个类似于:

的数组

[0 x1 0 0 y1 0 z1
 0 0 x2 0 y2 0 z2
 0 0 x3 0 0 y3 z3
 0 0 x4 0 0 y4 z4
 0 x5 0 0 0 y5 z5
 0 0 0 0 y6 0 0]

我需要确定连接线的集合(即连接点[x1,x2,x3 ..],[y1,y2,y3 ...],[z1,z2,z3 ..]的线)从数组中然后需要在每一行中找到最大值,即max {x1,x2,x3,...},max {y1,y2,y3 ..}等我试图使用kdtree进行最近邻搜索但是它返回相同的数组。我有大小的数组(200 x 8000)。有没有更简单的方法来做到这一点? THX。

2 个答案:

答案 0 :(得分:1)

我不知道任何提供您想要的功能的东西。如果您已经编写了逻辑,而且速度很慢,那么您是否考虑过Cython-ing代码。对于简单的类型化循环操作,您可以获得显着的加速。

答案 1 :(得分:1)

加速线搜索算法的另一种方法是预先计算每一行的起点,然后应用昂贵的逻辑来计算每个点的线。

我采用了有限的逻辑视图(因为你没有提供完整的行识别逻辑),它可以计算快速矢量化代码中的起点。

能够在快速矢量化代码中实现这样的事情的第一步是能够找出一行中的哪些点,但上面的直接点不是:

import numpy

# using the array that was provided in the question
a = """0 x1 0 0 y1 0 z1 
0 0 x2 0 y2 0 z2 
0 0 x3 0 0 y3 z3 
0 0 x4 0 0 y4 z4 
0 x5 0 0 0 y5 z5 
0 0 0 0 y6 0 0"""

array = numpy.array([int(v.strip()) if v.strip().isdigit() else i for i, v in enumerate(a.split(' '))]).reshape(6, 7) 

结果显示如下:

>>> print repr(array)
array([[ 0,  1,  0,  0,  4,  0,  6],
       [ 0,  0   9,  0, 11,  0, 13],
       [ 0,  0, 16,  0,  0, 19, 20],
       [ 0,  0, 23,  0,  0, 26, 27],
       [ 0, 29,  0,  0,  0, 33, 34],
       [ 0,  0,  0,  0, 39,  0,  0]])

从这里开始,我们可以进行一些努力:

 >>> print `numpy.roll(array, 1, axis=0)`
 array([[ 0,  0,  0,  0, 39,  0,  0],
        [ 0,  1,  0,  0,  4,  0,  6],
        [ 0,  0,  9,  0, 11,  0, 13],
        [ 0,  0, 16,  0,  0, 19, 20],
        [ 0,  0, 23,  0,  0, 26, 27],
        [ 0, 29,  0,  0,  0, 33, 34]])

可以将这些组合起来给我们行的垂直起点:

>>> potential_start_points = (array != 0) & (numpy.roll(array, 1, axis=0) == 0)
>>> # include the top row points, as they are certainly start points
>>> potential_start_points[0, :] = (array != 0)[0, :]
>>> print `potential_start_points`
array([[False,  True, False, False,  True, False,  True],
       [False, False,  True, False, False, False, False],
       [False, False, False, False, False,  True, False],
       [False, False, False, False, False, False, False],
       [False,  True, False, False, False, False, False],
       [False, False, False, False,  True, False, False]], dtype=bool)

从这里开始,可以优化矢量化逻辑以选择对角线等,但我很想迭代每个真则并应用更复杂的基于索引的逻辑。

xs, ys = numpy.where(potential_start_points)

for x, y in zip(xs, ys):
    # do more complex logic here ...

毕竟,在这种情况下,问题现在从迭代超过6x7 = 42的数字减少到迭代超过7。