Zastąpienie znaków innych niż angielski w tabelach atrybutów za pomocą ArcPy i Python?

9

Mam kilka plików kształtów, w których niektóre atrybuty zawierają znaki inne niż angielskie ÅĘÖ. Ponieważ niektóre zapytania nie działają z tymi znakami (szczególnie ChangeDetector ), próbowałem je wcześniej zmienić za pomocą prostego skryptu i dodać nowe ciągi znaków do innego pola.

Jednak zmiana znaków działa dobrze, ale nie aktualizuje pola za pomocą arcpy.UpdateCursor.

Jaki jest odpowiedni sposób rozwiązania tego?

Próbowałem to zrobić również za pomocą Kalkulatora pola, umieszczając „kod” w bloku kodu, z tym samym błędem.

Komunikat o błędzie:
Błąd w czasie wykonywania Traceback (ostatnie ostatnie połączenie): Plik „”, wiersz 1, w pliku „c: /gis/python/teststring.py”, wiersz 28, w val = kod (str (prow.Typkod)) UnicodeEncodeError: Kodek „ascii” nie może zakodować znaku u '\ xc4' na pozycji 3: porządek poza zakresem (128)

Kod:

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

Wartości Typkod są typu: [D, D, S, DDRĘ, TRĘ] itd.

Korzystam z ArcMap Basic (10.1) w systemie Windows 7.


Nowy komunikat o błędzie:
Błąd w czasie wykonywania Traceback (ostatnie ostatnie połączenie): Plik „”, wiersz 1, w pliku „c: /gis/python/teststring.py”, wiersz 29, w val = kod (Unicode (str (wiersz. Typkod), „utf-8”)) UnicodeEncodeError: kodek „ascii” nie może zakodować znaku u '\ xc4' w pozycji 3: numer porządkowy poza zakresem (128)

>>> val „DDRĘ”
>>> type(val) type ”str”


Wygląda na to, że dane wyjściowe z funkcji są jakoś niepoprawne. Kiedy jest zaangażowany ÅĘÖ, wraca data = u'DDR\xc4'i nie (tak jak to zamierzałem) data = 'DDRAE'. Wszelkie sugestie dotyczące tego, co może to powodować?

Jaskółka oknówka
źródło

Odpowiedzi:

7

Zbyt często mam do czynienia ze znakami specjalnymi, takimi jak ty w języku szwedzkim (ä, ö, å), ale także niektórymi innymi w językach takich jak portugalski i hiszpański (é, í, ú, ó itd.). Mam na przykład dane, w których nazwa miasta jest zapisana zwykłą łaciną, z usuniętymi wszystkimi akcentami, więc „Göteborg” staje się „Goteborg”, a „Åre” to „Are”. Aby wykonać połączenia i dopasować dane, muszę zastąpić akcenty alfabetem łacińskim.

Robiłem to tak, jak wcześniej pokazałeś we własnej odpowiedzi, ale ta logika wkrótce stała się dość kłopotliwa w utrzymaniu. Teraz używam modułu unicodedata, który jest już dostępny z instalacją Pythona i arcpy do iteracji funkcji.

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)

Zobacz link, aby uzyskać więcej informacji na temat korzystania z modułu Unicode w temacie Jaki jest najlepszy sposób na usunięcie akcentów w łańcuchu znaków Unicode w Pythonie?

Alex Tereshenkov
źródło
Rozumiem, jak to może być przydatne, ale co, jeśli musimy zachować postacie bez zmian? czy moglibyśmy zrobić trochę magii, aby zatrzymać te specjalne postacie?
Bogdan Mircea Stanciu
6

Okazuje się, że iteracja nad ÅĘÖ nie była taka łatwa. Jest to określane jako ciąg znaków Unicode i podczas sprawdzania instrukcji if, które muszą być użyte zamiast literału ÅĘÖ. Po tym, jak się zorientowałem, reszta to bułka z masłem :)

Wynikowy kod:

# -*- 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)
Jaskółka oknówka
źródło
1

Sprawdź, czy następujące działania:

val = code(unicode(str(prow.Typkod), "utf-8")
mapoholic
źródło
Dzięki! Pomogło to w przypisaniu val, ale nie w zapisaniu go do bieżącego wiersza (następnej linii). [Aktualizacja pytania o tę modyfikację.]
Martin
Masz na myśli, że ten wiersz się teraz nie powiedzie: prow.Typkod_U = val? Z tym samym błędem? Jaka jest wartość val po konwersji?
mapoholic
Dodałem kilka nowych informacji, w tym nowy komunikat o błędzie.
Martin