Заміна неанглійських символів у таблицях атрибутів за допомогою ArcPy та Python?


9

У мене є декілька форм-файлів, де деякі атрибути містять неанглійські символи ÅÄÖ. Оскільки деякі запити не працюють з цими символами (зокрема ChangeDetector ), я спробував їх змінити заздалегідь простим сценарієм і додати нові рядки до іншого поля.

Однак зміна символів працює добре, але не оновлює поле за допомогою arcpy.UpdateCursor.

Який належний спосіб вирішити це?

Я також спробував це зробити за допомогою калькулятора поля, публікуючи "код" в блоці коду, з тією ж помилкою.

Повідомлення про
помилку: Відстеження помилки виконання (останній дзвінок останній): Файл "", рядок 1, у файлі "c: /gis/python/teststring.py", рядок 28, у val = код (str (prow.Typkod)) UnicodeEncodeError: кодек 'ascii' не може кодувати символ u '\ xc4' у позиції 3: порядковий не знаходиться в діапазоні (128)

Код:

# -*- 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)

Значення Typkod мають тип: [D, D, S, DDRÄ, TRÄ] тощо.

Я використовую ArcMap Basic (10.1) в Windows 7.


Нове повідомлення про
помилку: Відстеження помилки під час виконання (останній виклик останній): Файл "", рядок 1, у файлі "c: /gis/python/teststring.py", рядок 29, у val = code (unicode (str (рядок) Typkod), "utf-8")) UnicodeEncodeError: "ascii" кодек не може кодувати символ u '\ xc4' у позиції 3: порядковий не знаходиться в діапазоні (128)

>>> val 'DDRÄ'
>>> type(val) тип 'str'


Схоже, що вихід з функції якимось чином неправильний. Коли є ÅÄÖ, він повертається, data = u'DDR\xc4'а не (як я мав намір) data = 'DDRAE'. Будь-які пропозиції щодо того, що може спричинити це?

Відповіді:


7

Я занадто часто маю справу зі спеціальними символами, такими як у вас шведською мовою (ä, ö, å), а також з деякими іншими мовами, такими як португальська та іспанська (é, í, ú, ó тощо). Наприклад, у мене є дані, де назва міста написана простою латиною з видаленими наголосами, тож "Гетеборг" стає "Гетеборг", а "Ере" - "Є". Для того, щоб виконувати приєднання та відповідати даним, я повинен замінити наголоси на англійський латинський символ.

Раніше я це робив, як ви показали спочатку у власній відповіді, але ця логіка незабаром стала досить громіздкою. Тепер я використовую модуль unicodedata, який уже доступний при встановленні Python та arcpy для ітерації функцій.

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)

Перейдіть за посиланням для отримання додаткової інформації про використання модуля unicodedata на сторінці Найкращий спосіб видалити наголоси в рядку unicode python?


Я бачу, як це може бути корисним, але що робити, якщо нам потрібно зберегти символи такими, які є? ми могли б зробити якусь магію, щоб зберегти цих особливих персонажів?
Богдан Мірча Станцю

6

Виявилося, що повторити ÅÄÖ було не так просто. Це позначається як рядок unicode і під час перевірки в if-операторах, які повинні використовуватися замість буквального ÅÄÖ. Після того, як я зрозумів це, решта - шматок пирога :)

Отриманий код:

# -*- 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

Перевірте, чи працює наступне:

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

Дякую! Це допомогло для призначення val, але не для його запису до поточного рядка (наступний рядок). [Оновлення питання з цією модифікацією.]
Мартін

Ви маєте на увазі, що цей рядок зараз не вдається: prow.Typkod_U = val? З тією ж помилкою? То яке значення val після конверсії?
мапоголік

Я додав нову інформацію, включаючи нове повідомлення про помилку.
Мартін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.