回答:
Pickはこのような問題のために作成されました。「if ... else」のマップ代数実装である「con」の「スイッチ」(または「ケース」)バージョンと考えてください。
たとえば、3つの重複するラスターがある場合、(Python)構文は次のようになります。
inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])
pick
は0ではなく1からインデックスを開始することに注意してください。
(コメントスレッドを参照)
NoData値に対処するには、最初にArcGISのNoData処理をオフにする必要があります。これを行うには、99999などのNoDataの代わりに特別な(ただし有効な)値を持つグリッドを作成します(ただし、表示できる有効な数値よりも大きい値を選択してください:これは後で便利です)。 。これには、次のようにIsNullリクエストを使用する必要があります。
p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)
たとえば、次の1行グリッドの場合を考えます(NoDataは "*"として表示されます)。
inRas01: 1 2 19 4 * * * *
inRas02: 9 2 * * 13 14 * *
inRas03: 17 * 3 * 21 * 23 *
その結果、各「*」の代わりに99999が配置されます。
次に、これらのすべてのラスターを、欠落しているブロック(穴)に対応するNoDataを持つ木製ブロックのフラットな配列として想像してください。これらのラスターを垂直に積み重ねると、ブロックはその下の穴に落ちます。NoData値の選択を回避するために、この動作が必要です。ブロックのスタックに垂直方向のギャップを入れないようにします。各タワーのブロックの順序は実際には重要ではありません。このために、データをランク付けすることで各タワーを取得できます。
q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])
この例では、
q01: 1 2 3 4 13 14 23 99999
q02: 9 2 19 99999 21 99999 99999 99999
q03: 17 99999 99999 99999 99999 99999 99999 99999
ランクは最低から最高に向かっているため、q01には各場所の最低値が含まれ、q02には2番目に低い値が含まれる、などです。NoDataコードは、すべての有効な数値が収集されるまで表示されません。ある大きな任意の有効な数字より。
ランダム選択中にこれらのNoDataコードが選択されないようにするには、各場所にスタックされているブロックの数を知る必要があります。これにより、有効な値の数がわかります。これを処理する1つの方法は、NoDataコードの数をカウントし、それを選択グリッドの総数から差し引くことです。
n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])
これは
n0: 3 2 2 1 2 1 1 0
n = 0(選択できるものがないため)のケースを処理するには、それらをNoDataに設定します。
n = SetNull(n0 == 0, n0)
今
n: 3 2 2 1 2 1 1 *
これにより、最終的な計算で(一時的な)NoDataコードが消えることも保証されます。1とnの間のランダムな値を生成します。
inPositionRaster = 1 + int(n * CreateRandomRaster())
たとえば、このラスターは次のようになります。
inPositionRaster: 3 2 1 1 2 1 1 *
すべての値は、1と[n]の対応する値の間にあります。
以前とまったく同じように値を選択します。
selection = Pick(inPositionRaster, [q01, q02, q03])
これは
selection: 17 2 3 4 21 14 23 *
すべて問題がないことを確認するには、NoDataコード(この例では99999)を持つすべての出力セルを選択してみてください。何もないはずです。
この実行例では3つのグリッドのみを使用して選択していますが、任意の数のグリッドに簡単に一般化できる方法で記述しました。グリッドがたくさんあるので、(繰り返された操作をループするための)スクリプトを書くことは非常に貴重です。
pick
常にNoDataを出力することです(ただし、inPositionRasterと選択されたラスターの両方がセルに有効な値を持っている場合、おそらく結果はそのセルは、他のラスターに何が含まれているかに関係なく、選択したラスターの値である必要があります)。どのような代替行動を考えていますか?
PythonおよびArcGIS 10を使用し、次の構文を持つcon関数を使用します。
Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})
ここでの考え方は、ランダムラスタの値が0.5未満であるかどうかを確認することです。ラスタ1を選択した場合は、ラスタ2を選択します。NoData
+ data = NoData
したがって、最初にこれらの値NoData
を0に再分類します。
import arcpy
from arcpy import env
from arcpy.sa import *
env.workspace = "C:/sapyexamples/data"
ras1_NoNull = Con(IsNull("elevation1"),0, "elevation1") # remove NoData
ras2_NoNull = Con(IsNull("elevation2"),0, "elevation2") # remove NoData
randRaster = CreateRandomRaster(100, 2, Extent(0, 0, 150, 150)) # raster generated between 0 and 1; 100 is seed value
outCon = Con(randRaster < 0.5, ras1_NoNull, ras2_NoNull)
outCon.save("C:/outcon.img") # save raster
編集:NoData
部分を省略できるように値を追加していないことに気づきました。
Con(IsNull(ras1), 0, ras2)
NoData
ですか?ランダムに選択するときに選択されないようにするだけですか?
同じ範囲とセルサイズのランダムラスタ(ヘルプ)を作成するだけです。次に、CON(ヘルプ)を使用して、ランダムラスタのセルの値が128未満の場合(ランダムラスタが0〜255の場合)、最初のラスタから値を選択するように設定します。それ以外の場合は、2番目のラスタから値を選択します。
理にかなっていると思います:)