10 votos

¿Cómo reemplazar caracteres no ingleses en tablas de atributos utilizando ArcPy y Python?

Tengo unos shapefiles donde algunos atributos contienen caracteres no ingleses ÅÄÖ. Dado que algunas consultas no funcionan con estos caracteres (específicamente ChangeDetector), intenté cambiarlos previamente con un script simple y agregar las nuevas cadenas a otro campo.

Sin embargo, el cambio de caracteres funciona bien pero no se actualiza el campo con arcpy.UpdateCursor.

¿Cuál es una forma adecuada de resolver esto?

También he intentado hacer esto a través de la Calculadora de Campos mientras publicaba "código" en el bloque de código, con el mismo error.

~~Mensaje de error:
Error en tiempo de ejecución Traceback (llamada más reciente en último): Archivo "", línea 1, en Archivo "c:/gis/python/teststring.py", línea 28, en val = code(unicode(str(prow.Typkod), "utf-8")) UnicodeEncodeError: el códec 'ascii' no puede codificar el carácter u'\xc4' en la posición 3: ordinal no está en el rango(128)~~

Código:

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

Los valores de Typkod son del tipo: [D, D, S, DDRÄ, TRÄ] etc.

Utilizo ArcMap Basic (10.1) en Windows 7.


Nuevo mensaje de error:
Error en tiempo de ejecución Traceback (llamada más reciente en último): Archivo "", línea 1, en Archivo "c:/gis/python/teststring.py", línea 29, en val = code(unicode(str(row.Typkod), "utf-8")) UnicodeEncodeError: el códec 'ascii' no puede codificar el carácter u'\xc4' en la posición 3: ordinal no está en el rango(128)

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


Parece que la salida de la función está incorrecta de alguna manera. Cuando hay ÅÄÖ involucrados, devuelve data = u'DDR\xc4' y no (como era mi intención) data = 'DDRAE'. ¿Alguna sugerencia sobre qué podría estar causando esto?

9voto

Alex Tereshenkov Puntos 13433

Me encuentro muy a menudo tratando con caracteres especiales como los que se tienen en sueco (ä,ö,å), pero también algunos otros presentes en otros idiomas como portugués y español (é,í,ú,ó, etc.). Por ejemplo, tengo datos donde el nombre de una ciudad está escrito en latín simple sin acentos, por lo que "Göteborg" se convierte en "Goteborg" y "Åre" se convierte en "Are". Para poder realizar uniones y coincidir los datos, debo reemplazar los acentos por el caracter en base al latín inglés.

Solía hacer esto como se muestra en tu propia respuesta al principio, pero esta lógica pronto se volvió bastante engorrosa de mantener. Ahora uso el módulo unicodedata que ya está disponible con la instalación de Python y arcpy para iterar las entidades.

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)

Vea el enlace para obtener más información sobre el uso del módulo unicodedata en ¿Cuál es la mejor manera de eliminar acentos en una cadena unicode de Python?

0 votos

Veo cómo esto podría ser útil, pero ¿qué pasa si necesitamos mantener los caracteres tal como están? ¿podríamos hacer algo mágico para conservar esos caracteres especiales?

6voto

Martin Puntos 2872

Resulta que iterar sobre ÅÄÖ no fue tan fácil. Se refiere a como una cadena unicode, y al verificar en las declaraciones if que se debe usar en lugar de los literales ÅÄÖ. Después de descubrir eso, ¡el resto fue pan comido :)

Código resultante:

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

1voto

Rafael Almeida Puntos 141

Verifica si lo siguiente funciona:

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

0 votos

¡Gracias! Eso sí ayudó para la asignación de val, pero no para escribirlo en la fila actual (la línea siguiente). [Actualizando la pregunta con esta modificación.]

0 votos

¿Significa que esta línea ahora falla: prow.Typkod_U = val? ¿Con el mismo error? Entonces, ¿cuál es el valor de val después de la conversión?

0 votos

He añadido nueva información, incluido el nuevo mensaje de error.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X