Thay thế các ký tự không phải tiếng Anh trong bảng thuộc tính bằng ArcPy và Python?


9

Tôi có một vài shapefile trong đó một số thuộc tính chứa các ký tự không phải tiếng Anh. Vì một số truy vấn không hoạt động với các ký tự này (cụ thể là ChangeDetector ), tôi đã cố gắng thay đổi chúng trước bằng một tập lệnh đơn giản và thêm các chuỗi mới vào trường khác.

Tuy nhiên, thay đổi trong các ký tự hoạt động tốt nhưng không cập nhật trường với arcpy.UpdateC tiền.

Một cách thích hợp để giải quyết điều này là gì?

Tôi cũng đã cố gắng thực hiện điều này thông qua Máy tính Trường trong khi đăng "mã" lên codeblock, với cùng một lỗi.

Thông báo lỗi:
Lỗi thời gian chạy TracBack (cuộc gọi gần đây nhất): Tệp "", dòng 1, trong Tệp "c: /gis/python/testopes.py", dòng 28, trong val = code (str (prow.Typkod)) UnicodeEncodeError: 'ascii' codec không thể mã hóa ký tự u '\ xc4' ở vị trí 3: thứ tự không nằm trong phạm vi (128)

Mã số:

# -*- coding: cp1252 -*-
def code(infield):
    data = ''
    for i in infield:
##        print i
        if i == 'Ä':
            data = data + 'AE'
        elif i == 'ä':
            data = data + 'ae'
        elif i == 'Å':
            data = data + 'AA'
        elif i == 'å':
            data = data + 'aa'
        elif i == 'Ö':
            data = data + 'OE'
        elif i == 'ö':
            data = data + 'oe'
        else:
            data = data + i
    return data


shp = r'O:\XXX\250000\DB\ArcView\shape.shp'

prows = arcpy.UpdateCursor(shp)

for prow in prows:
    val = code(unicode(str(prow.Typkod), "utf-8"))
    prow.Typkod_U = val
    print val
    prows.updateRow(prow)

Các giá trị của typkod thuộc loại: [D, D, S, DDRÄ, TRÄ], v.v.

Tôi sử dụng ArcMap Basic (10.1) trên Windows 7.


Thông báo lỗi mới: Lỗi thời
gian chạy TracBack (cuộc gọi gần đây nhất): Tệp "", dòng 1, trong Tệp "c: /gis/python/testopes.py", dòng 29, trong val = code (unicode (str (row. Typkod), "utf-8")) UnicodeEncodeError: 'ascii' codec không thể mã hóa ký tự u '\ xc4' ở vị trí 3: thứ tự không nằm trong phạm vi (128)

>>> val 'DDRÄ'
>>> type(val) loại 'str'


Có vẻ như đầu ra từ chức năng là sai. Khi có liên quan, nó trở lại data = u'DDR\xc4'và không (như ý định của tôi) data = 'DDRAE'. Bất kỳ đề xuất về những gì có thể gây ra điều này?

Câu trả lời:


7

Tôi quá thường xuyên phải đối phó với các ký tự đặc biệt như bạn có trong tiếng Thụy Điển (ä, ö, å), nhưng cũng có một số người khác trình bày bằng các ngôn ngữ khác như tiếng Bồ Đào Nha và tiếng Tây Ban Nha (é, í, ú, ó, v.v.). Chẳng hạn, tôi có dữ liệu trong đó tên của thành phố được viết bằng tiếng Latinh đơn giản với tất cả các dấu được loại bỏ, do đó "Göteborg" trở thành "Goteborg" và "Åre" là "Are". Để thực hiện các phép nối và khớp dữ liệu, tôi phải thay thế các dấu bằng ký tự gốc tiếng Anh Latinh.

Tôi đã từng làm điều này như bạn đã thể hiện trong câu trả lời của riêng bạn trước tiên, nhưng logic này sớm trở nên khá cồng kềnh để duy trì. Bây giờ tôi sử dụng mô-đun unicodingata đã có sẵn với cài đặt Python và arcpy để lặp lại các tính năng.

import unicodedata
import arcpy
import os

def strip_accents(s):
   return ''.join(c for c in unicodedata.normalize('NFD', s)
                  if unicodedata.category(c) != 'Mn')

arcpy.env.workspace = r"C:\TempData_processed.gdb"
workspace = arcpy.env.workspace

in_fc = os.path.join(workspace,"FC")
fields = ["Adm_name","Adm_Latin"]
with arcpy.da.UpdateCursor(in_fc,fields) as upd_cursor:
    for row in upd_cursor:
        row[1] = strip_accents(u"{0}".format(row[0]))
        upd_cursor.updateRow(row)

Xem liên kết để biết thêm thông tin về cách sử dụng mô-đun unicodingata tại Cách tốt nhất để xóa dấu trong chuỗi unicode python là gì?


Tôi thấy làm thế nào điều này có thể hữu ích, nhưng nếu chúng ta cần giữ các nhân vật như thế nào thì sao? chúng ta có thể làm một số phép thuật để giữ những nhân vật đặc biệt đó không?
Bogdan Mircea Stanciu

6

Hóa ra lặp đi lặp lại ÅÄÖ không dễ dàng như vậy. Nó được gọi là một chuỗi unicode và khi kiểm tra các câu lệnh if phải được sử dụng thay cho chữ. Sau khi tôi nhận ra điều đó, phần còn lại là một miếng bánh :)

Mã kết quả:

# -*- coding: cp1252 -*-
def code(infield):
    data = ''
    for i in infield:
##        print i
        if i == u'\xc4': 
            data = data + 'AE'
        elif i == u'\xe4': 
            data = data + 'ae'
        elif i == u'\xc5': 
            data = data + 'AA'
        elif i == u'\xe5': 
            data = data + 'aa'
        elif i == u'\xd6': 
            data = data + 'OE'
        elif i == u'\xf6': 
            data = data + 'oe'
        else:
            data = data + i
    return data


shp = arcpy.GetParameterAsText(0)
field = arcpy.GetParameterAsText(1)
newfield = field + '_U'
arcpy.AddField_management(shp, newfield, 'TEXT')

prows = arcpy.UpdateCursor(shp)

for row in prows:
    row.newfield = code(row.field)
    prows.updateRow(row)

1

Xem nếu các công việc sau đây:

val = code(unicode(str(prow.Typkod), "utf-8")

Cảm ơn! Điều đó đã giúp cho việc gán val, nhưng không phải để viết nó vào hàng hiện tại (dòng sau). [Cập nhật câu hỏi với sửa đổi này.]
Martin

Bạn có nghĩa là dòng này bây giờ thất bại: prow.Typkod_U = val? Với cùng một lỗi? Vậy giá trị val sau khi chuyển đổi là gì?
mapoholic

Tôi đã thêm một số thông tin mới, bao gồm thông báo lỗi mới.
Martin
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.