Exportieren nur bestimmter Spalten in eine CSV-Datei in ArcGIS for Desktop?


15

Ich habe ein Python-Skript mit arcpy geschrieben, das eine Polygon-Feature-Class in eine File-Geodatabase ausgibt. Ich habe eine Funktion zum Exportieren der Attribute in eine separate CSV-Datei hinzugefügt. Ich verwende den Code, den ich in diesem Beitrag gefunden habe und der perfekt funktioniert. Dieser Code exportiert jedoch jede Spalte in der Feature-Class. Ich möchte nur die Felder exportieren , die die folgenden Namen nicht haben: OBJECTID, Shapeoder Shape_Length.

Meine CSV-Datei wurde erfolgreich generiert und enthält die Felder oder nicht ordnungsgemäß . Das Feld wird jedoch in die Datei geschrieben. Ein Beispielwert, der in dieses Feld geschrieben wird, ist:OBJECTIDShape_LengthShape

<geoprocessing describe geometry object object at 0x28CB90A0>

Ich habe eine Zeile hinzugefügt, um die Feldnamen zu drucken, während sie durchlaufen und überraschenderweise Shapenicht gedruckt werden. Es ist, als ob ArcGIS es verbirgt oder ihm einen anderen Namen gibt.

Der Code für meine Funktion ist unten:

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()

Weiß jemand, was hier los ist?


Ich habe meinen Code geändert, um dem Rat von @sgrieve zu folgen, und es wurde immer noch das ShapeFeld geschrieben. Wenn ich eine Zeile hinzufüge, um die Feldnamen zu drucken, während sie durchlaufen werden, werden alle Felder mit Ausnahme des ShapeFelds aufgelistet , es wird jedoch weiterhin in die CSV geschrieben. Außerdem wurden die X- und Y-Koordinaten des Polygons als zwei neue Spalten hinzugefügt und die Spalten wurden nicht mehr an den Spaltennamen ausgerichtet.

Ich habe die Zeile geändert, in der @sgrieve die folgenden Felder deklariert:

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

Der neue Code funktioniert gut, aber ich bin mir immer noch nicht sicher, was das Problem war. Weiß jemand, was los war? Was ist Shapelos mit dem Feld?


Müssen Sie hier Python verwenden? Es ist sehr einfach, die nicht gewünschten Felder über die Registerkarte Felder in den Ebeneneigenschaften auszublenden. Anschließend exportieren Sie die Daten aus der geöffneten Attributtabelle in das CSV-Format (Text File), um nur die gewünschten Felder abzurufen.
PolyGeo

Ja, ich möchte, dass dies zu meinem Skript hinzugefügt wird. Es ist eine Kundenanforderung.
Fezter

Weiß noch jemand, was hier los ist? Weiß jemand, warum das ShapeFeld in die Datei geschrieben wurde? Während der Code von @ sgrieve möglicherweise meinen Code verbesserte, konnte das Problem nicht behoben werden.
Fezter

1
Mein Ansatz wäre, MakeTableView gefolgt von TableToTable zu verwenden . Wenn Ihr Ansatz es nicht schafft, könnte dies eine andere Möglichkeit sein, Ihr Shape-Feld zu "verlieren".
PolyGeo

Antworten:


14

Ich habe Ihren Code vereinfacht und den Fehler mit dem korrigiert in 10.1 eingeführten da-Modul . Das Lesen von Daten mithilfe von Cursorn wird erheblich vereinfacht. In Verbindung mit dem withBefehl sollte dieser Code stabiler sein als bei Verwendung der älteren Methode für den Dateizugriff.

Es funktioniert, indem eine Liste aller Felder erstellt und dann die nicht gewünschten Felder aus der Liste entfernt werden. Dies könnte im Rahmen des Listenverständnisses geschehen, wäre aber ziemlich chaotisch und unpythonisch. Sobald die Liste der gewünschten Felder erstellt wurde, wird sie mit dem da-Modul verwendet, um alle Daten in diesen Feldern in den Cursor einzulesen. Dies kann dann durchgeschleift und unter Verwendung eines anderen Listenverständnisses in die Datei geschrieben werden, um alle Felder zu verbinden. Dies hat den Vorteil, dass für eine beliebige Anzahl von Feldern gearbeitet werden kann, die größer als 0 sind.

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')

Danke @sgrieve. Ich habe den von Ihnen geposteten Code kopiert und erhalte eine CSV-Datei, die fast genau das ist, was ich will. Es gibt jedoch einige Probleme. 1. Der ShapeFeldname wird noch geschrieben, die Shape-Werte jedoch nicht. 2. Es wurden nun zwei neue Spalten am Anfang der Tabelle hinzugefügt, wodurch die Spalten effektiv nach rechts verschoben werden. Diese Spalten scheinen die X- und Y-Koordinaten des Polygons zu sein.
Fezter

3
Ok, ich denke, ich habe es herausgefunden. Es war etwas mit dem ShapeFeld los - vielleicht, weil es ein Geometrietyp ist. Also habe ich die Zeile geändert, in der Sie fieldsFolgendes deklarieren : fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] Das hat den Trick getan. Ich bin mir nicht sicher, warum es ohne das nicht funktioniert hat.
Fezter

2

Ich glaube, ich bin auf dasselbe Problem gestoßen und habe herausgefunden, warum Ihr Feld "Shape" nicht entfernt wurde. Bei Verwendung dieser Schleife:

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

Ich habe festgestellt, dass es eigentlich nur jedes andere Feld entfernt. Es wird also zuerst eine Schleife durchlaufen, 'OBJECTID' entfernen, und dann wird das 'Shape'-Feld an die Stelle verschoben, die zuvor von' OBJECTID 'in der Liste gehalten wurde, und es wird zur nächsten weitergegangen, die dann' Shape_Length 'wäre.

Es war also nicht speziell die Shape-Geometrie, die das Entfernen verhinderte, sondern nur die Tatsache, dass bei Verwendung dieses Skripts alle anderen Felder entfernt wurden.


Gute Idee, in diesem Fall könnte das Problem durch das Erstellen mehrerer if-Anweisungen (nicht elifs) behoben werden.
Schlaf6

Es ist keine gute Idee, eine Liste in einer Schleife zu mutieren. Sie können unerwartete Ergebnisse erzielen. Siehe diesen Beitrag zu einem ähnlichen Thema, das ich hatte.
Fezter

0

Ein Schlüssel zu einem Aspekt davon ist die Bestimmung des richtigen Namens für die nicht benutzerdefinierten Felder der Objekt-ID und der Geometrie. Der Typ des Geometriefelds ist Double, was in diesem Fall nicht hilfreich ist. Mit der Beschreibungsfunktion kann man den richtigen Namen für diese Felder über verschiedene Dateitypen hinweg bestimmen (z. B. Shapefile v File GDB usw.).

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)]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.