ส่งออกเฉพาะบางคอลัมน์ไปยังไฟล์ CSV ใน ArcGIS for Desktop หรือไม่


15

ฉันได้เขียนสคริปต์ไพ ธ อนโดยใช้ arcpy ซึ่งแสดงคลาสของรูปหลายเหลี่ยมในฐานข้อมูลไฟล์ ฉันได้เพิ่มฟังก์ชั่นเพื่อส่งออกคุณสมบัติไปยังไฟล์ CSV แยกต่างหาก ฉันใช้รหัสที่ฉันพบในโพสต์นี้ซึ่งทำงานได้อย่างสมบูรณ์ อย่างไรก็ตามรหัสนั้นจะส่งออกทุกคอลัมน์ในคลาสคุณลักษณะ ฉันเพียงต้องการส่งออกเขตข้อมูลที่ไม่ได้มีรายชื่อดังต่อไปนี้: OBJECTID, หรือShapeShape_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ฟิลด์ ถ้าผมเพิ่มบรรทัดที่จะพิมพ์ชื่อฟิลด์ในขณะที่มัน iterates ผ่านพวกเขาก็จะแสดงรายการทุกสาขายกเว้นShapeฟิลด์ แต่มันยังคงเขียนไปแบบ CSV นอกจากนี้ยังเพิ่มพิกัด X และ Y ของรูปหลายเหลี่ยมเป็นคอลัมน์ใหม่สองคอลัมน์และคอลัมน์ไม่สอดคล้องกับชื่อคอลัมน์อีกต่อไป

ฉันได้แก้ไขบรรทัดที่ @sgrieve ประกาศเขตข้อมูลดังต่อไปนี้:

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

รหัสใหม่ทำงานได้ดี แต่ฉันก็ยังไม่แน่ใจว่าปัญหาคืออะไร ไม่มีใครรู้ว่าเกิดอะไรขึ้น? การจัดการกับShapeสนามคืออะไร?


คุณต้องการใช้ Python ที่นี่หรือไม่? มันง่ายมากที่จะซ่อนฟิลด์ที่คุณไม่ต้องการโดยใช้แท็บฟิลด์ของคุณสมบัติเลเยอร์ จากนั้นจากตารางแอตทริบิวต์เปิดส่งออกข้อมูลไปยังไฟล์ข้อความ (ซึ่งเป็นรูปแบบ CSV) เพื่อรับเฉพาะฟิลด์ที่คุณต้องการ
PolyGeo

ใช่ฉันต้องการเพิ่มในสคริปต์ของฉัน มันเป็นความต้องการของลูกค้า
Fezter

มีใครอีกบ้างที่รู้ว่าเกิดอะไรขึ้นที่นี่ ไม่มีใครรู้ว่าทำไมShapeสนามถูกเขียนลงในไฟล์? ในขณะที่รหัสของ @ sgrieve อาจปรับปรุงรหัสของฉัน แต่ก็ไม่ได้แก้ปัญหา
Fezter

1
วิธีการของฉันนี้จะใช้MakeTableViewตามTableToTable หากวิธีการของคุณไม่ไปถึงที่นั่นอาจเป็นอีกวิธีหนึ่งในการ "สูญเสีย" เขตข้อมูลรูปร่างของคุณ
PolyGeo

คำตอบ:


14

ฉันทำให้รหัสของคุณง่ายขึ้นและแก้ไขข้อผิดพลาดโดยใช้โมดูล da ที่แนะนำใน 10.1 ช่วยเพิ่มความคล่องตัวในการอ่านข้อมูลโดยใช้เคอร์เซอร์และใช้ร่วมกับwithคำสั่งรหัสนี้ควรมีเสถียรภาพมากกว่าถ้าใช้วิธีเก่ากว่าในการเข้าถึงไฟล์

มันทำงานได้โดยการทำรายการของเขตข้อมูลทั้งหมดแล้วลบเขตข้อมูลที่คุณไม่ต้องการจากรายการ สิ่งนี้สามารถทำได้ภายในรายการความเข้าใจ แต่มันจะค่อนข้างยุ่งและไม่ได้เป็น pythonic เมื่อสร้างรายการของเขตข้อมูลที่ต้องการแล้วจะใช้กับโมดูล 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ชื่อเขตข้อมูลยังคงถูกเขียน แต่ค่ารูปร่างไม่ 2. ขณะนี้มีคอลัมน์ใหม่สองคอลัมน์ที่เพิ่มไปยังจุดเริ่มต้นของตารางได้อย่างมีประสิทธิภาพการย้ายคอลัมน์ไปทางขวา คอลัมน์เหล่านี้ดูเหมือนจะเป็นพิกัด X และ Y ของรูปหลายเหลี่ยม
Fezter

3
โอเคฉันคิดว่าฉันทำงานเสร็จแล้ว มีบางอย่างเกิดขึ้นกับShapeสนาม - อาจเป็นเพราะมันเป็นรูปทรงเรขาคณิต ดังนั้นฉันได้แก้ไขบรรทัดที่คุณประกาศว่าfieldsเป็นดังต่อไปนี้: fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] นั่นเป็นการหลอกลวง ไม่แน่ใจว่าทำไมมันไม่ทำงานโดยที่แม้ว่า
Fezter

2

ฉันคิดว่าฉันพบปัญหาเดียวกันและค้นพบสาเหตุที่พื้นที่ "รูปร่าง" ของคุณไม่ถูกลบ เมื่อใช้ลูปนี้:

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

ฉันได้ค้นพบว่าจริง ๆ แล้วมันเป็นการลบเขตข้อมูลอื่นเท่านั้น ดังนั้นก่อนจะวนซ้ำลบ 'OBJECTID' จากนั้นฟิลด์ 'รูปร่าง' จะไปยังตำแหน่งที่ 'OBJECTID' ไว้ก่อนหน้านี้ในรายการดังนั้นจึงย้ายไปยังอีกอันหนึ่งซึ่งจะเป็น

ดังนั้นมันจึงไม่ใช่รูปทรงเรขาคณิตเฉพาะที่ป้องกันไม่ให้ถูกลบออกไปเพียงข้อเท็จจริงที่ว่ามันจะลบฟิลด์อื่นทุกครั้งเมื่อใช้สคริปต์นี้


ความคิดที่ดีซึ่งในกรณีนี้การสร้างหลายรายการถ้างบ (ไม่ใช่ elifs) สามารถแก้ไขปัญหาได้
Sleep6

ไม่ใช่ความคิดที่ดีที่จะกลายพันธุ์รายการในลูป คุณสามารถได้รับผลลัพธ์ที่ไม่คาดคิด ดูโพสต์นี้ในประเด็นที่คล้ายกันที่ฉันมี
Fezter

0

กุญแจสำคัญในด้านนี้คือการกำหนดชื่อที่เหมาะสมสำหรับเขตข้อมูลที่ผู้ใช้ไม่ได้กำหนดของ ID วัตถุและรูปทรงเรขาคณิต ประเภทของเขตข้อมูลรูปทรงเรขาคณิตเป็นสองเท่าซึ่งไม่เป็นประโยชน์ในกรณีนี้ การใช้ฟังก์ชั่นอธิบายเราสามารถกำหนดชื่อที่ถูกต้องสำหรับฟิลด์เหล่านี้ข้ามประเภทไฟล์ (เช่นไฟล์ 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)]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.