Chỉ xuất một số cột nhất định sang tệp CSV trong ArcGIS cho Máy tính để bàn?


15

Tôi đã viết một tập lệnh python bằng cách sử dụng arcpy, nó đưa ra một lớp tính năng đa giác vào Cơ sở dữ liệu địa lý tệp. Tôi đã thêm một chức năng để xuất các thuộc tính vào một tệp CSV riêng biệt. Tôi đang sử dụng mã mà tôi đã tìm thấy trong bài viết này hoạt động hoàn hảo. Tuy nhiên, mã đó xuất mọi cột trong lớp tính năng. Tôi chỉ muốn export các lĩnh vực mà không có tên sau: OBJECTID, Shape, hoặc Shape_Length.

Tệp CSV của tôi tạo thành công và chính xác nó không bao gồm các trường OBJECTIDhoặc Shape_Length. Tuy nhiên, Shapetrường được ghi vào tệp. Một giá trị mẫu được ghi vào trường đó là:

<geoprocessing describe geometry object object at 0x28CB90A0>

Tôi đã thêm một dòng để in tên trường khi nó lặp qua chúng và đáng ngạc nhiên, Shapekhông được in. Như thể ArcGIS đang che giấu nó hoặc đặt cho nó một cái tên khác.

Mã cho chức năng của tôi là dưới đây:

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

Có ai biết chuyện gì đang xảy ra ở đây không?


Tôi đã sửa đổi mã của mình để làm theo lời khuyên của @sgrieve và nó vẫn đang viết Shapetrường. Nếu tôi thêm một dòng để in tên trường vì nó lặp qua chúng, nó sẽ liệt kê tất cả các lĩnh vực ngoại trừ các Shapelĩnh vực, tuy nhiên nó vẫn ghi vào CSV. Nó cũng đã thêm tọa độ X và Y của đa giác dưới dạng hai cột mới và các cột không còn thẳng hàng với tên cột.

Tôi đã sửa đổi dòng trong đó @sgrieve tuyên bố các trường như sau:

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

Mã mới hoạt động tốt, nhưng tôi vẫn không chắc vấn đề là gì. Có ai biết chuyện gì đang xảy ra không? Thỏa thuận với Shapelĩnh vực này là gì?


Bạn có cần sử dụng Python ở đây không? Thật dễ dàng để ẩn các trường bạn không muốn sử dụng tab Trường của Thuộc tính lớp. Sau đó, từ bảng thuộc tính mở Xuất dữ liệu sang định dạng Tệp văn bản (là CSV) để chỉ nhận các trường bạn muốn.
PolyGeo

Có, tôi muốn điều này được thêm vào kịch bản của tôi. Đó là một yêu cầu của khách hàng.
Fezter

Có ai khác biết những gì đang xảy ra ở đây? Có ai biết tại sao các Shapelĩnh vực đã được ghi vào tập tin? Mặc dù mã của @ sgrieve có thể cải thiện mã của tôi, nhưng nó không giải quyết được vấn đề.
Fezter

1
Cách tiếp cận của tôi với điều này sẽ là sử dụng MakeTableView theo sau là TableToTable . Nếu cách tiếp cận của bạn không đạt được điều đó thì đây có thể là một cách khác để "mất" trường Hình dạng của bạn.
PolyGeo

Câu trả lời:


14

Tôi đã đơn giản hóa mã của bạn và sửa lỗi bằng cách sử dụng mô đun da được giới thiệu trong 10.1. Nó hợp lý hóa đáng kể việc đọc dữ liệu bằng con trỏ và được sử dụng cùng với withlệnh, mã này sẽ ổn định hơn so với việc sử dụng phương thức truy cập tệp cũ hơn.

Nó hoạt động bằng cách tạo một danh sách tất cả các trường và sau đó xóa các trường bạn không muốn khỏi danh sách. Điều này có thể được thực hiện trong phạm vi hiểu danh sách, nhưng nó sẽ khá lộn xộn và không pythonic. Khi danh sách các trường mong muốn đã được tạo, nó được sử dụng với mô đun da để đọc tất cả dữ liệu trong các trường này vào con trỏ. Điều này sau đó có thể được lặp qua và ghi vào tệp bằng cách hiểu danh sách khác để tham gia tất cả các trường. Điều này có lợi ích làm việc cho bất kỳ số lượng trường lớn hơn 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')

Cảm ơn @sgrease. Tôi đã sao chép mã bạn đã đăng và tôi nhận được một tệp CSV gần như những gì tôi muốn. Nhưng có một vài vấn đề. 1. Tên Shapetrường vẫn được ghi nhưng giá trị Shape thì không. 2. Hiện tại có hai cột mới đã được thêm vào đầu bảng có hiệu quả dịch chuyển các cột sang phải. Các cột của chúng dường như là tọa độ X và Y của đa giác.
Fezter

3
Ok, tôi nghĩ rằng tôi đã làm việc ra. Có một cái gì đó đang xảy ra với Shapelĩnh vực này - có thể bởi vì nó là một loại hình học. Vì vậy, tôi đã sửa đổi dòng mà bạn tuyên bố fieldslà như sau: fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] đó là mẹo. Không chắc tại sao nó không hoạt động mà không có.
Fezter

2

Tôi nghĩ rằng tôi đã gặp phải vấn đề tương tự và phát hiện ra lý do tại sao trường "Hình dạng" của bạn không bị xóa. Khi sử dụng vòng lặp này:

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

Tôi đã phát hiện ra nó thực sự chỉ loại bỏ mọi lĩnh vực khác. Vì vậy, trước tiên, nó sẽ lặp lại, loại bỏ 'OBRIID', và sau đó trường 'Hình dạng' đi đến vị trí được giữ trước đó bởi 'OBRIID' trong danh sách, do đó, nó sẽ chuyển sang cái tiếp theo, sau đó sẽ là 'Shape_Lạng'.

Vì vậy, nó không đặc biệt là hình dạng Hình dạng đã ngăn không cho nó bị xóa, thực tế là nó loại bỏ mọi trường khác khi sử dụng tập lệnh này.


Ý tưởng tốt, trong trường hợp tạo nhiều câu lệnh if (không phải elif) có thể giải quyết vấn đề.
Ngủ

Nó không phải là một ý tưởng tốt để thay đổi một danh sách trong một vòng lặp. Bạn có thể nhận được kết quả bất ngờ. Xem bài này về một vấn đề tương tự tôi đã có.
Fezter

0

Một chìa khóa cho một khía cạnh này là xác định tên thích hợp cho các trường không xác định người dùng của id đối tượng và hình học. Loại trường hình học là Double, không hữu ích trong trường hợp này. Sử dụng chức năng mô tả, người ta có thể xác định tên thích hợp cho các trường này trong các loại tệp (ví dụ: tệp shapefile v gdb, v.v., giảm bớt rất nhiều đau buồn vì oid sẽ thay đổi ngay cả trong cùng một loại tệp ...).

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)]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.