ビッグデータ用のPythonコードの合理化


34

次のワークフローでポイントシェープファイルを取得するように設計されたPythonコードがあります。

  1. ポイントをマージ
  2. 互いに1 m以内のポイントが1つのポイントになるようにポイントを統合します
  3. フィーチャレイヤーを作成します。z<10のポイントが選択されています
  4. バッファポイント
  5. ポリゴンからラスター1mの解像度
  6. 再分類、ここで1-9 = 1; NoData = 0

各シェープファイルには、約5x7 kmをカバーする約250,000〜350,000ポイントがあります。入力として使用されるポイントデータは、ツリーの位置を表します。各ポイント(つまりツリー)には、クラウン半径を表す「z」値が関連付けられており、バッファプロセスで使用されます。私の目的は、最終的なバイナリ出力を別のプロセスで使用して、天蓋カバーを記述するラスターを作成することです。

4つのシェープファイルでテストを実行したところ、700MBのラスターが生成され、35分かかりました(i5プロセッサと8GB RAM)。このプロセスを3500個のシェープファイルで実行する必要があるので、プロセスを合理化するためのアドバイスをいただければ幸いです(添付コードを参照)。一般的に、ジオプロセシングビッグデータを処理する最良の方法は何ですか?より具体的には、効率を高めるのに役立つ可能性のあるコードまたはワークフローの調整はありますか?

編集

ジオプロセシングタスクの時間(全体の%):

  • マージ= 7.6%
  • 積分= 7.1%
  • Lyrへの機能= 0
  • バッファー= 8.8%
  • ポリゴンからラスター= 74.8%
  • 再分類= 1.6%

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

# Import arcpy module
import arcpy

# Check out any necessary licenses
arcpy.CheckOutExtension("spatial")

# Script arguments
temp4 = arcpy.GetParameterAsText(0)
if temp4 == '#' or not temp4:
    temp4 = "C:\\gdrive\\temp\\temp4" # provide a default value if unspecified

Reclassification = arcpy.GetParameterAsText(1)
if Reclassification == '#' or not Reclassification:
    Reclassification = "1 9 1;NODATA 0" # provide a default value if unspecified

Multiple_Value = arcpy.GetParameterAsText(2)
if Multiple_Value == '#' or not Multiple_Value:
    Multiple_Value = "C:\\t1.shp;C:\\t2.shp;C:\\t3.shp;C:\\t4.shp" # provide a default value if unspecified

# Local variables:
temp_shp = Multiple_Value
Output_Features = temp_shp
temp2_Layer = Output_Features
temp_Buffer = temp2_Layer
temp3 = temp_Buffer

# Process: Merge
arcpy.Merge_management(Multiple_Value, temp_shp, "x \"x\" true true false 19 Double 0 0 ,First,#,C:\\#########omitted to save space

# Process: Integrate
arcpy.Integrate_management("C:\\gdrive\\temp\\temp.shp #", "1 Meters")

# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(temp_shp, temp2_Layer, "z <10", "", "x x VISIBLE NONE;y y VISIBLE NONE;z z VISIBLE NONE;Buffer Buffer VISIBLE NONE")

# Process: Buffer
arcpy.Buffer_analysis(temp2_Layer, temp_Buffer, "z", "FULL", "ROUND", "NONE", "")

# Process: Polygon to Raster
arcpy.PolygonToRaster_conversion(temp_Buffer, "BUFF_DIST", temp3, "CELL_CENTER", "NONE", "1")

# Process: Reclassify
arcpy.gp.Reclassify_sa(temp3, "Value", Reclassification, temp4, "DATA")

3
これらは、パフォーマンスの向上を試み、見つけることに焦点を当てすることができますように-それは時間の大部分は、1つまたはいくつかのステップに入っているかどうかを確立するために、いくつかのパフォーマンスのタイミングコードに置く価値があるかもしれない
PolyGeo

5
ArcPyを使用し続けている場合、パフォーマンスを改善するための選択肢はあまりないと思います。たぶん、あなたはこれを行うために他のツールを見ることができますか?FMEや多分postgisのようなツール?
tmske

3
使用されているピクセルタイプは明確ではありませんが、「バイト」(あるべき)の場合、生データストレージはラスターごとに5000x7000 = 35Mb(〜33.4MB)になりますが、実際にはそれほど大きくありません。ただし、3500の次のディメンション(時間ディメンション?)では、合計rawサイズが〜114GBに増加します。
マイクT

5
この説明からアルゴリズムの実行内容(または実行予定)を伝えることはできませんが、ほとんどの場合、ポイントバッファーとそれに続くラスタ化は、ポイントのラスタライズとそれに続く焦点統計(通常は平均または合計)に置き換える必要があります。結果は同じになりますが、長いバッファリングとポリラスタライゼーションのステップを回避することにより、はるかに高速に取得できます。私は(大幅に)大幅な追加の高速化が得られると考えていますが、手順の説明があいまいであるため、具体的なアドバイスを提供できません。
whuber

2
ポイントの周囲のバッファーは可変サイズです(ポイントのz値に基づきます)。私はまだ焦点統計を行うために、結果値をz値で分割し、各セットでラスターと焦点統計を行う必要があります(統計値として最大値を持つ円形近傍の半径としてzを使用します)。次に、最大統計を使用して9つのラスターすべてでセル統計を実行し、結果をまとめます。(おそらく、ビッグデータセットでバッファリングおよびラスタライズするよりもはるかに高速です。)
blord-castillo

回答:


10

役立つアルゴリズムの変更。

マージまたは統合する前に、最初に選択を実行します。これにより、最も高価な後の機能が大幅に削減されます。

マージと統合はどちらもメモリを消費するため、フィーチャクラスを取り込むときにフィーチャを削除し続け、バイナリツリーでマージを実行して、マージと統合のサイズを小さくしてください。たとえば、4つのシェープファイルの場合、2つのシェープファイルをマージして統合します。さらに2つのシェープファイルをマージして統合します。結果の2つのフィーチャクラスをマージして統合します。

ジョブキューは、シェープファイル参照のキューとして開始されます。結果を配置する結果キューもあります。並列処理ワーカーのrun()メソッドは、次の操作を実行します。キューから2つのアイテムを取り出します。アイテムが取得されない場合(キューが空の場合)、ワーカーを終了します。1つのアイテムが取得された場合、そのアイテムを結果キューに直接配置します。

アイテムごとに2つのアイテムが取得される場合:シェープファイルの場合は、z <10を選択し、in_memoryフィーチャクラスを作成します。それ以外の場合は、既にin_memoryフィーチャクラスであり、選択手順をスキップします。2つのin_memoryフィーチャクラスをマージして、新しいin_memoryフィーチャクラスを作成します。元の2つのフィーチャクラスを削除します。新しいフィーチャクラスで統合を実行します。そのフィーチャクラスを結果キューに配置します。

次に、外側のwhileループを実行します。ループはシェープファイルキューから始まり、長さが1より大きいかどうかをテストします。次に、ワーカーを介してキューを実行します。結果キューの長さが1より大きい場合、whileループは、結果キューが1 in_memoryフィーチャクラスになるまで、ワーカーを介して実行される別の並列処理を実行します。

たとえば、3500個のシェープファイルで開始する場合、最初のキューには3500個のジョブがあります。2番目には1750のジョブがあります。875、438、219、110、55、28、14、7、4、2、1。大きなボトルネックはメモリになります。十分なメモリがない場合(そして、その場合は最初の結果キューの作成でメモリが不足します)、アルゴリズムを修正して、一度に3つ以上のフィーチャクラスをマージしてから統合します。より長い処理時間と引き換えに、最初の結果キューのサイズ。オプションで、出力ファイルを作成し、in_memoryフィーチャクラスの使用をスキップできます。これにより、かなり遅くなりますが、メモリのボトルネックを乗り越えます。

単一のフィーチャクラスで終わるすべてのシェープファイルでマージと統合を実行した後にのみ、バッファ、ポリゴンからラスター、および再分類を実行します。そうすれば、これら3つの操作は1回だけ実行され、ジオメトリをシンプルに保つことができます。


データがメモリに収まる場合は、in_memoryワークスペースを使用するための+1 。ジオプロセシング操作を大幅に高速化します。
ライアンダルトン

これは良いものです。ダイアグラムといくつかの擬似コード(または実際のコード)を使用すると、さらに改善されると思います。
blah238

ええ、コードにコミットする時間があればいいのにと思います。とにかく、新しい並列処理デモスクリプトを作成する必要があります。
blord-castillo

14

最初に行うことは、Windows 7のリソースモニターやVista / XPのperfmonなどを使用してシステムのリソース使用率を監視しCPUメモリ、またはIOにバインドされているかどうかを把握することです。

メモリまたはIOバウンドの場合、ハードウェアをアップグレードするか、問題のサイズを小さくするか、アプローチを完全に変更する以外にできることはほとんどありません。

CPUに縛られていると判断した場合は、multiprocessingモジュールまたは他の多くのPythonベースの並列処理パッケージの 1つを試して、より多くのCPUコアを使用して操作を高速化できるかどうかを確認します。

一般に、マルチプロセッシングと並列処理の秘trickは、次のような優れたパーティションスキームを見つけることです。

  1. 入力をより小さなワーキングセットに分割し、意味のある方法で結果を再結合できます。
  2. 最小限のオーバーヘッドを追加します(シリアル処理と比較して避けられないものもあります)。
  3. ワーキングセットのサイズを調整して、システムのリソースを最大限に活用してパフォーマンスを最適化できます。

この回答で作成したスクリプトを開始点として使用できます。ArcGISfor ArcGIS Desktopにシャドウを作成するためのAvenueコードを移植しますか?

このテーマに関するESRI Geoprocessingブログ投稿も参照してください。Python マルチプロセッシング-アプローチと考慮事項

あなたが使用しているツールのより「ブラックボックス」な性質のために、私が取り組んでいたよりきめの細かいジオメトリ配列ではなく、あなたのケースはさらに困難になると思います。おそらく、NumPyアレイでの作業が役に立つかもしれません。

また、もしあなたがarcpyを超えて見たいなら、私はいくつかの興味深い読み物に出くわしました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.