Експорт лише певних стовпців у файл CSV в ArcGIS for Desktop?


15

Я написав сценарій python, використовуючи arcpy, який виводить клас функції багатокутника у File Geodatabase. Я додав функцію експорту атрибутів в окремий файл CSV. Я використовую код, який я знайшов у цій публікації, який працює чудово. Однак цей код експортує кожен стовпець класу функцій. Я тільки хочу , щоб експортувати поля , які не мають наступні назви: OBJECTID, Shapeабо Shape_Length.

Мій файл CSV генерується успішно, і він правильно не включає поля OBJECTIDабо Shape_Length. Тим НЕ менше, Shapeполе буде записано в файл. Приклад значення, яке записується в це поле:

<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 багатокутника у вигляді двох нових стовпців, а стовпці вже не узгоджуються з назвами стовпців.

Я змінив рядок, де @sgrieve оголошує поля такими:

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

Новий код працює чудово, але я все ще не впевнений, у чому проблема. Хтось знає, що відбувалося? Яка угода з Shapeполем?


Чи потрібно тут використовувати Python? Дуже легко приховати поля, які ви не хочете, використовуючи вкладку "Поля" властивостей шару. Потім з відкритої таблиці атрибутів Експортуйте дані у формат текстового файлу (який є CSV), щоб отримати лише ті поля, які ви хочете.
PolyGeo

Так, я хочу, щоб це було додано до мого сценарію. Це вимога до клієнта.
Фестер

Хтось ще знає, що тут відбувається? Хтось знає, чому це Shapeполе записували у файл? Хоча код @ sgrieve, можливо, покращив мій код, це не вирішило проблему.
Фестер

1
Моїм підходом до цього було б використання MakeTableView, за яким слід TableToTable . Якщо ваш підхід не потрапить до цього, це може бути іншим способом "втратити" поле "Форма".
PolyGeo

Відповіді:


14

Я спростив ваш код і виправив помилку, використовуючи модуль da, введений у 10.1. Він значно впорядковує зчитування даних за допомогою курсорів, і використовуваний разом із withкомандою цей код повинен бути стабільнішим, ніж якби він використовував старіший метод доступу до файлів.

Він працює, склавши список усіх полів, а потім видаливши поля, які ви не бажаєте, зі списку. Це можна зробити в межах розуміння списку, але це було б досить безладно і непітонічно. Після створення списку бажаних полів його використовують з модулем 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. Зараз на початку таблиці додано два нові стовпці, що фактично зміщують стовпці вправо. У них стовпці є координатами X та Y багатокутника.
Фестер

3
Гаразд, я думаю, я це розробив. З Shapeполем щось відбувалося - можливо, тому, що це тип геометрії. Отже, я змінив рядок, де ви заявляєте, fieldsщо такий: fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] це зробив трюк. Не впевнений, чому без цього не обійшлося.
Фестер

2

Я думаю, що я зіткнувся з тією ж проблемою і виявив причину того, що ваше поле "Форма" не було видалено. Під час використання цієї петлі:

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

Я виявив, що це фактично лише видалення кожного іншого поля. Таким чином, спочатку він пройде цикл, видалить OBJECTID ', а потім поле' Shape 'перейде до місця, яке раніше у списку було відзначено' OBJECTID ', тож перейде до наступного, яке потім буде' Shape_Length '.

Тож саме геометрія форми не перешкоджала її видаленню, а лише те, що вона видаляє всі інші поля при використанні цього сценарію.


Хороша ідея. У цьому випадку створення декількох, якщо заяви (а не elifs) можуть вирішити проблему.
Сон6

Недоцільно мутувати список у циклі. Ви можете отримати несподівані результати. Дивіться цей пост у подібному питанні, яке я мав.
Fezter

0

Ключовим фактором для цього є визначення належної назви для не визначених користувачем полів ідентифікатора об’єкта та геометрії. Тип поля геометрії - подвійний, що в цьому випадку не є корисним. Використовуючи функцію опису, можна визначити належне ім'я для цих полів у різних типах файлів (наприклад, shapefile 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)]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.