Nicht-englische Zeichen in Attributtabellen mit ArcPy und Python ersetzen?


9

Ich habe einige Shapefiles, in denen einige der Attribute die nicht englischen Zeichen ÅÄÖ enthalten. Da einige Abfragen mit diesen Zeichen nicht funktionieren (insbesondere ChangeDetector ), habe ich versucht, sie im Voraus mit einem einfachen Skript zu ändern und die neuen Zeichenfolgen einem anderen Feld hinzuzufügen.

Das Ändern von Zeichen funktioniert jedoch einwandfrei, aktualisiert das Feld jedoch nicht mit arcpy.UpdateCursor.

Was ist ein geeigneter Weg, um dies zu lösen?

Ich habe auch versucht, dies über den Feldrechner zu tun, während ich "Code" mit demselben Fehler in den Codeblock gepostet habe.

Fehlermeldung:
Laufzeitfehler Traceback (letzter Aufruf zuletzt): Datei "", Zeile 1, in Datei "c: /gis/python/teststring.py", Zeile 28, in val = code (str (prow.Typkod)) UnicodeEncodeError: Der Codec 'ascii' kann das Zeichen u '\ xc4' in Position 3 nicht codieren: Ordnungszahl nicht im Bereich (128)

Code:

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

Die Werte von Typkod sind vom Typ: [D, D, S, DDRÄ, TRÄ] usw.

Ich verwende ArcMap Basic (10.1) unter Windows 7.


Neue Fehlermeldung:
Laufzeitfehler Traceback (letzter Aufruf zuletzt): Datei "", Zeile 1, in Datei "c: /gis/python/teststring.py", Zeile 29, in val = code (Unicode (str (Zeile). Typkod), "utf-8")) UnicodeEncodeError: Der Codec 'ascii' kann das Zeichen u '\ xc4' in Position 3 nicht codieren: Ordnungszahl nicht im Bereich (128)

>>> val 'DDRÄ'
>>> type(val) Typ 'str'


Es scheint, als ob die Ausgabe der Funktion irgendwie falsch ist. Wenn es um ÅÄÖ geht, kehrt es zurück data = u'DDR\xc4'und nicht (wie es meine Absicht war) data = 'DDRAE'. Irgendwelche Vorschläge, was dies verursachen könnte?

Antworten:


7

Ich habe es zu oft mit Sonderzeichen zu tun, wie Sie sie auf Schwedisch haben (ä, ö, å), aber auch mit einigen anderen, die in anderen Sprachen wie Portugiesisch und Spanisch (é, í, ú, ó usw.) dargestellt werden. Zum Beispiel habe ich Daten, bei denen der Name der Stadt in einfachem Latein geschrieben ist und alle Akzente entfernt sind, sodass "Göteborg" zu "Göteborg" wird und "Åre" zu "Are" wird. Um die Verknüpfungen durchzuführen und die Daten abzugleichen, muss ich die Akzente durch das englische lateinische Zeichen ersetzen.

Früher habe ich dies getan, wie Sie zuerst in Ihrer eigenen Antwort gezeigt haben, aber diese Logik wurde bald ziemlich umständlich zu pflegen. Jetzt verwende ich das Unicodedata-Modul, das bereits mit Python-Installation und arcpy verfügbar ist, um die Funktionen zu iterieren.

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)

Weitere Informationen zur Verwendung des Unicodedata-Moduls finden Sie unter dem Link unter Was ist der beste Weg, um Akzente in einer Python-Unicode-Zeichenfolge zu entfernen?


Ich sehe, wie dies nützlich sein könnte, aber was ist, wenn wir die Zeichen so lassen müssen, wie sie sind? Könnten wir etwas Magie tun, um diese Sonderzeichen zu behalten?
Bogdan Mircea Stanciu

6

Es stellte sich heraus, dass es nicht so einfach war, über ÅÄÖ zu iterieren. Es wird als Unicode-Zeichenfolge bezeichnet und beim Einchecken der if-Anweisungen, die anstelle des Literals ÅÄÖ verwendet werden müssen. Nachdem ich das herausgefunden hatte, war der Rest ein Kinderspiel :)

Resultierender Code:

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

Überprüfen Sie, ob Folgendes funktioniert:

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

Vielen Dank! Das hat zwar beim Zuweisen von geholfen val, aber nicht beim Schreiben in die aktuelle Zeile (die folgende Zeile). [Aktualisieren der Frage mit dieser Änderung.]
Martin

Sie meinen, diese Zeile schlägt jetzt fehl: prow.Typkod_U = val? Mit dem gleichen Fehler? Was ist der Wert nach der Konvertierung?
Mapoholic

Ich habe einige neue Informationen hinzugefügt, einschließlich der neuen Fehlermeldung.
Martin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.