numpyでの信号侵入


8

問題は、下の図のように、一連の障害物を通過する信号(光や音など)の伝播をモデル化することです。信号は底面(地形)を通過できませんが、障害物を通過できます。通過した障害物の数を数えたい。

ここに画像の説明を入力してください

地形と障害物は2Dの数の多い配列(x、y、z)にあります。これが私がすることです:

output = numpy.zeros(terrain.shape)

obstacles = terrain + obstacle_heights


for i in xrange (obstacles.shape[0]):
    for j in xrange (obstacles.shape[1]):

        mask = obstacles[i,j] > terrain[i,j:]
        output[i,j:][mask] +=1

結果は、[0, 0, 0, 1, 1, 1, 2, 3, 4, 4, 4 ...]行ごとのようなものになります。

この方法は正常に機能します(提供された地形の谷はを使用して埋められますnumpy.maximum.accumulate)。さて、ベクトル化されたソリューションを使用してスピードアップすることは可能でしょうか?


1
興味深い質問です。どのソリューションを探しているのか、どのデータが入力データなのかを詳しく説明できますか?信号を表すラインの作成(ラインストリングレイヤーとして)を探していると思いますが、この場合、ソース形式に加えて方向も指定する必要があります。
mgri 2017年

音響と光の減衰(ヘイズ、煙など)の両方に興味があります。簡単にするために、信号は地形に平行に(垂直に)、地形グリッドに平行に(水平に)移動します。「シグナル」とは、numpyマトリックスに対する単純なイテレーターのみを意味します。
Zoran

1
そして、信号の高さはどうですか?
dmh126 2017年

信号の高さは任意です。たとえば、人間の高さを1,7メートルとすると、その値の地形を(一時的に)上げることができます。私はソースからの距離と高さを割ったウィッヒ角度サイズ使用している私のコード-しかし、それはここでは関係ありませんが、それは私には思える>(?)
ゾラン

ベクトル化は間違いなく可能です。FFTはベクトル化できます(jakevdp.github.io/blog/2013/08/28/understanding-the-fft)。しかし、障害物。形状[0]と障害物。形状[1]が何を表すかを理解するのに苦労しています。
John Powell

回答:


1

上記のコメントにあるように、おそらく操作をベクトル化してforループを削除し、より効率的にすることができます。

ただし、少し異なる方法で問題を検討する場合(しきい値処理など)、scipy ndimageのツールを利用して障害を数えることができます。

まず、起点に関係なく、信号の高さで地形データにしきい値を設定して、信号が存在する可能性のあるブール配列を取得します。

signal_reach = terrain < signal_height

次に、このndimage.labelメソッドを使用して、個別の領域をグループ化できます。

from scipy import ndimage
signal_regions, region_count = ndimage.label(signal_reach)

これが完了したら、信号の発信元セルと一致するリージョンIDを取得します。あなたの場合、それは最初の列になります。

import numpy as np
origin_labels = np.unique(signal_regions[:, 0]) # or whatever indexes meet the start of the signal
# ndimage lables are greater than 1, 0 is an unlabeled region
origin_labels = origin_lables[origin_lables > 0]

ここで、しきい値は、信号が地形+障害物を遮る場所numpy.isinです。今回は、を使用して、対象外の領域または関心領域を除外します。

area_of_interest = np.isin(signal_regions, origin_labels)
signal_intercepted = (obstacles >= signal_height) & area_of_interest

そして、最後のラウンドでndimage.labelは、地形によって遮断された領域を既に除外しているため、遮断された障害の数がわかります。

obstacles_hit, obstacle_count = ndimage.label(signal_intercepted)

ここにはもう少しコードがありますが、2つの大きな利点があります。

  • forループがないということは、コードがかなり高速であることを意味します。
  • また、計算の目的で、信号の起点はテレインラスタ上の任意の場所または多数のセルにすることができます。

1
これは有望なアプローチのようです!1月にテストを行い、問題がなければ動作フラグを付けます。
Zoran
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.