Sostituzione di caratteri non inglesi nelle tabelle degli attributi usando ArcPy e Python?


9

Ho alcuni shapefile in cui alcuni degli attributi contengono i caratteri non inglesi ÅÄÖ. Poiché alcune query non funzionano con questi caratteri (in particolare ChangeDetector ), ho provato a modificarli in anticipo con un semplice script e aggiungere le nuove stringhe in un altro campo.

Tuttavia, la modifica dei caratteri funziona correttamente ma non aggiorna il campo con arcpy.UpdateCursor.

Qual è un modo appropriato per risolvere questo?

Ho anche provato a farlo tramite il calcolatore di campo durante la pubblicazione di "codice" nel blocco codice, con lo stesso errore.

Messaggio di errore:
errore di runtime Traceback (ultima chiamata più recente): file "", riga 1, nel file "c: /gis/python/teststring.py", riga 28, in val = code (str (prow.Typkod)) UnicodeEncodeError: il codec 'ascii' non può codificare il carattere u '\ xc4' in posizione 3: ordinale non compreso nell'intervallo (128)

Codice:

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

I valori di Typkod sono del tipo: [D, D, S, DDRÄ, TRÄ] ecc.

Uso ArcMap Basic (10.1) su Windows 7.


Nuovo messaggio di errore:
Errore di runtime Traceback (ultima chiamata più recente): file "", riga 1, nel file "c: /gis/python/teststring.py", riga 29, in val = code (unicode (str (riga. Typkod), "utf-8")) UnicodeEncodeError: il codec 'ascii' non può codificare il carattere u '\ xc4' in posizione 3: ordinale non nell'intervallo (128)

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


Sembra che l'output della funzione sia in qualche modo sbagliato. Quando c'è ÅÄÖ coinvolto, ritorna data = u'DDR\xc4'e non (come era mia intenzione) data = 'DDRAE'. Qualche suggerimento su cosa potrebbe causare questo?

Risposte:


7

Troppo spesso mi occupo di personaggi speciali come quelli che hai in svedese (ä, ö, å), ma anche di altri che presentano in altre lingue come portoghese e spagnolo (é, í, ú, ó ecc.). Ad esempio, ho dei dati in cui il nome della città è scritto in latino con tutti gli accenti rimossi, quindi il "Göteborg" diventa "Goteborg" e "Åre" è "Are". Per eseguire i join e abbinare i dati, devo sostituire gli accenti al carattere inglese di base latina.

Lo facevo come hai mostrato prima nella tua risposta, ma questa logica divenne presto piuttosto ingombrante da mantenere. Ora uso il modulo unicodedata che è già disponibile con l'installazione di Python e arcpy per iterare le funzionalità.

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)

Vedi il link per maggiori informazioni sull'uso del modulo unicodedata in Qual è il modo migliore per rimuovere gli accenti in una stringa Unicode Python?


Vedo come questo potrebbe essere utile, ma cosa succede se dobbiamo mantenere i personaggi così come sono? potremmo fare un po 'di magia per mantenere quei personaggi speciali?
Bogdan Mircea Stanciu,

6

Risulta che ripetere ÅÄÖ non è stato così facile. Viene indicato come una stringa unicode e al momento del check-in delle istruzioni if ​​che devono essere utilizzate al posto del letterale ÅÄÖ. Dopo averlo capito, il resto è stato un gioco da ragazzi :)

Codice risultante:

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

Vedi se il seguente funziona:

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

Grazie! Ciò ha aiutato per l'assegnazione di val, ma non per scriverlo nella riga corrente (la riga seguente). [Aggiornamento della domanda con questa modifica.]
Martin

Vuoi dire che questa riga ora fallisce: prow.Typkod_U = val? Con lo stesso errore? Quindi qual è il valore val dopo la conversione?
mapoholic

Ho aggiunto alcune nuove informazioni, incluso il nuovo messaggio di errore.
Martin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.