4

を使用してarcpy、私の目的は、さらに処理するためにフィーチャクラスをリストにストックすることです。各行は{'field name': value}、ジオメトリを含む の辞書になります。

このタスクを達成するための最も Pythonic な方法は、リスト内包表記を使用することです。

fc = '/path/to/fc'
fields = [f.name for f in arcpy.ListFields(fc)]   # get field list
features = [[row.getValue(f) for f in fields] for row in arcpy.SearchCursor(fc)]

この方法はデータに対して機能しますが、リスト内のジオメトリはすべて同じです (fc で最後に取得されたジオメトリ)。SearchCursor のこの動作は、既に StackOverflow でコメントされています

別のアプローチを試しました:

fc = '/path/to/fc'
shape_field = arcpy.Describe(fc).shapeFieldName

# load geometry in a list
geom = arcpy.Geometry()
feat = [{shape_field: f} for f in arcpy.CopyFeatures_management(fc, geom)] # slow

# load data in a list
fields = [f.name for f in arcpy.ListFields(fc)]
data = [dict([(f, row.getValue(f)) for f in fields if f != shape_field]) for row in arcpy.SearchCursor(fc)] # slow

# merge
merge = zip(feat, data)
merge = [dict([(k, v) for adict in line for (k, v) in adict.items()]) for line in merge] # sorry for that...

それは私のデータセットで動作しますが:

  • 遅いです。
  • データと偉業が同じ順序であると断言するのが安全かどうかはわかりません。

それについて何か意見はありますか?

4

1 に答える 1

5

可能な限り、10.1 を使用するように移行してください。これarcpy.daは、カーソル用のはるかにパフォーマンスの高い API です。私は辞書を元に戻すというまさにこのトピックに関するログ投稿を書きました。内部でリサイクル カーソルを使用するため、ジオメトリはすべて同じになります。そのため、10.0shape.__geo_interface__では代わりにグラブして使用AsShapeし、ジオメトリ オブジェクトに戻します。

行を取得する順序はかなり恣意的です。where 句のないシェープファイルでは毎回同じであると期待できますが、それだけなので、2 パス アプローチは実際には信頼できません。

これらすべてを考慮すると、次のようなことができます。

def cursor_to_dicts(cursor, field_names):
    for row in cursor:
        row_dict = {}
        for field in field_names:
            val = row.getValue(field)
            row_dict[field] = getattr(val, '__geo_interface__', val)
        yield row_dict

fc = '/path/to/fc'
fields = [f.name for f in arcpy.ListFields(fc)]   # get field list
features = list(cursor_to_dicts(arcpy.SearchCursor(fc), fields))

魔法はgetattr()呼び出しです。value.__geo_interface__存在する場合は取得してみてください。そうでない場合は、デフォルトでvalue.

この質問は Python 言語全般に関するものではなく、arcpyGIS 固有の API ( ) に関するものであるため、今後 gis.stackexchange でこのような質問をした方がよいかもしれません。

于 2012-08-08T22:26:22.423 に答える