1

次のような配列があります。

[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)の配列があります。これを行う簡単な方法はありますか?どうも。

4

2 に答える 2

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)

ここから、ベクトル化されたロジックを改良して対角線などを選択することができますが、各Trueを繰り返し処理して、より複雑なインデックスベースのロジックを適用したいと思います。

xs, ys = numpy.where(potential_start_points)

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

結局のところ、この場合の問題は、6x7=42の数値を反復することから7を超える反復に減少しました。

于 2012-07-19T18:06:29.857 に答える
1

箱から出してすぐに望む機能を提供するものは何も知りません。すでにロジックを書いていて、それが単に遅い場合は、コードを Cython 化することを検討しましたか。単純な型付きループ操作の場合、大幅な高速化が得られます。

于 2012-07-19T16:02:33.770 に答える