ArcGIS for Desktopで特定の列のみをCSVファイルにエクスポートしますか?


15

ポリゴンフィーチャクラスをファイルジオデータベースに出力するarcpyを使用して、Pythonスクリプトを記述しました。属性を別のCSVファイルにエクスポートする機能を追加しました。この投稿で見つけた完全に機能するコードを使用しています。ただし、そのコードは、フィーチャクラスのすべての列をエクスポートします。:私は、以下の名前を持っていないフィールドをエクスポートするOBJECTIDShapeまたはShape_Length

CSVファイルが正常に生成され、またはフィールドが正しく含まれていません。ただし、フィールドファイルに書き込まれます。そのフィールドに書き込まれる値の例は次のとおりです。OBJECTIDShape_LengthShape

<geoprocessing describe geometry object object at 0x28CB90A0>

フィールド名を印刷する行を追加しましたが、フィールド名を繰り返し処理するため、驚くことにShape印刷されません。ArcGISが非表示にしたり、別の名前を付けたりするようです。

私の関数のコードは次のとおりです。

def exportToTable():
    """ 
        Exports the final outputs to a CSV File.
    """

    # Create path to CSV File (note the varialbe outputPath is declared elsewhere).
    CSVFile = outputPath+'\\FinalOutput.csv'
    arcpy.AddMessage("Created CSV File: %s" %CSVFile)

    # Get all fields in FinalOutput feature class and remove unwanted fields.
    fields = arcpy.ListFields('FinalOutput')
    for field in fields:
        arcpy.AddMessage("Field.name is:"+field.name) #not printing 'Shape' field name
        if field.name in (['OBJECTID', 'Shape', 'Shape_Length']):
            fields.remove(field)

    i = 1
    f=open(CSVFile, 'w')
    for field in fields:
        #--write the wanted field names to the output file
        if i < len(fields):
            f.write('%s,' % field.name)
            i += 1
        else:
            f.write('%s\n' % field.name)

    # Use a search cursor to iterate through the rows of the table and write them to the CSV file.
    rows = arcpy.SearchCursor('FinalOutput')
    for row in rows:
        i = 1
        for field in fields:
            if i < len(fields):
                f.write('%s,' % row.getValue(field.name))
                i += 1
            else:
                f.write('%s\n' % row.getValue(field.name))
    del rows
    f.close()

誰がここで何が起こっているのか知っていますか?


@sgrieveのアドバイスに従うようにコードを変更しましたが、まだShapeフィールドを書いていました。私はそれがそれらを反復処理として、フィールド名を印刷する行を追加すると、それはすべてのフィールド一覧表示を除くShapeフィールドを、まだそれはまだCSVに書き込みます。また、ポリゴンのX座標とY座標を2つの新しい列として追加し、列は列名と一致しなくなりました。

@sgrieveがフィールドを宣言する行を次のように変更しました。

fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry']

新しいコードは正常に機能しますが、問題が何であるかはまだわかりません。誰が何が起こっているのか知っていますか?Shapeフィールドとの取引は何ですか?


ここでPythonを使用する必要がありますか?レイヤープロパティの[フィールド]タブを使用して、不要なフィールドを非表示にするのは非常に簡単です。次に、開いている属性テーブルからデータをテキストファイル(CSV)形式にエクスポートして、必要なフィールドのみを取得します。
PolyGeo

はい、これをスクリプトに追加したいです。これはクライアントの要件です。
フェスター

ここで何が起こっているか他の誰かが知っていますか?Shapeフィールドがファイルに書き込まれた理由を誰もが知っていますか?@sgrieveのコードによってコードが改善される可能性はありますが、問題は解決しませんでした。
フェスター

1
これに対する私のアプローチは、使用することですMakeTableViewが続いTableToTable。アプローチがうまくいかない場合、これはShapeフィールドを「失う」別の方法かもしれません。
PolyGeo

回答:


14

コードを単純化し、10.1で導入されたdaモジュールを使用してエラーを修正しました。カーソルを使用したデータの読み取りを大幅に合理化し、withコマンドと組み合わせて使用​​すると、このコードはファイルアクセスの古い方法を使用した場合よりも安定するはずです。

すべてのフィールドのリストを作成し、不要なフィールドをリストから削除することで機能します。これはリストの理解の範囲内で行うことができますが、かなり面倒で非Python的です。目的のフィールドのリストが作成されると、daモジュールで使用され、これらのフィールドのすべてのデータがカーソルに読み込まれます。その後、これをループし、別のリスト内包表記を使用してすべてのフィールドを結合してファイルに書き込むことができます。これには、0より大きい任意の数のフィールドで機能するという利点があります。

import arcpy

fc = 'C:\\antenna_shp\\cables.shp'
CSVFile = 'C:\\antenna_shp\\FinalOutput.csv'

fields = [f.name for f in arcpy.ListFields(fc)]

for i,f in enumerate(fields):
    if f == 'Shape' or f == 'Shape_Length' or f == 'OBJECTID':
        del fields[i]

with open(CSVFile, 'w') as f:
    f.write(','.join(fields)+'\n') #csv headers
    with arcpy.da.SearchCursor(fc, fields) as cursor:
        for row in cursor:
            f.write(','.join([str(r) for r in row])+'\n')

ありがとう@sgrieve。あなたが投稿したコードをコピーし、ほとんど私が望むものであるCSVファイルを取得します。しかし、いくつかの問題があります。1. Shapeフィールド名はまだ書き込まれていますが、Shape値は書き込まれていません。2.表の先頭に追加された2つの新しい列があり、列を効果的に右にシフトしています。これらの列は、ポリゴンのXおよびY座標のように見えます。
フェスター

3
わかりました、私はそれを解決したと思います。Shapeフィールドで何かが行われていました-おそらくそれがジオメトリタイプだからです。だから、あなたが宣言する行をfields次のように変更しました:fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] それはトリックをしました。しかし、それなしでは機能しなかった理由はわかりません。
フェスター

2

私は同じ問題にぶつかり、フィールド「Shape」が削除されなかった理由を発見したと思います。このループを使用する場合:

if field.name in (['OBJECTID', 'Shape', 'Shape_Length']):
    fields.remove(field)

実際に他のすべてのフィールドを削除するだけであることがわかりました。そのため、最初にループし、「OBJECTID」を削除してから、「Shape」フィールドがリスト内の「OBJECTID」によって以前保持されていた場所に移動し、次の「Shape_Length」に移動します。

したがって、このスクリプトを使用するときに他のすべてのフィールドを削除するという事実だけで、削除することを妨げていたのは、具体的にはShapeジオメトリではありませんでした。


この場合、複数のifステートメント(elifsではない)を作成することで問題を解決できます。
Sleep6 14

ループ内でリストを変更するのは得策ではありません。予期しない結果が生じる可能性があります。私が持っていた同様の問題に関するこの投稿を参照してください。
フェスター

0

この1つの側面の鍵は、オブジェクトIDとジオメトリのユーザー定義でないフィールドの適切な名前を決定することです。ジオメトリフィールドのタイプはDoubleで、この場合は役に立ちません。describe関数を使用すると、ファイルタイプ全体でこれらのフィールドの適切な名前を特定できます(シェープファイルvファイルgdbなど。OIDが同じファイルタイプ内でも時々変更されるため、多くの悲しみを軽減します...)。

fc = 'path to my featureclass'
desc = arcpy.Describe(fc)
fields = [f.name for f in arcpy.ListFields(fc) if f.name not in (desc.OIDFieldName, desc.areaFieldName, desc.lengthFieldName), desc.shapeFieldName)]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.