使用ArcPy和Python替换属性表中的非英文字符?


9

我有一些shapefile,其中某些属性包含非英语字符ÅÄÖ。由于某些查询不适用于这些字符(特别是ChangeDetector),因此我尝试使用一个简单的脚本预先更改它们,并将新字符串添加到另一个字段中。

但是,更改字符效果很好,但不能使用arcpy.UpdateCursor更新该字段。

解决这个问题的合适方法是什么?

我也曾尝试通过字段计算器来执行此操作,同时将“代码”发布到代码块中,出现相同的错误。

错误消息:
运行时错误回溯(最近一次调用最近):文件“”,行1,在文件“ c:/gis/python/teststring.py”,行28,在val =代码(str(prow.Typkod)) UnicodeEncodeError:'ascii'编解码器无法在位置3处编码字符u'\ xc4':顺序号不在范围内(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Ä]等。

我在Windows 7上使用ArcMap Basic(10.1)。


新的错误消息:
运行时错误回溯(最近一次调用最近):文件“”,行1,在文件“ c:/gis/python/teststring.py”,行29,在val = code(unicode(str(row。 Typkod),“ utf-8”))UnicodeEncodeError:“ ascii”编解码器无法在位置3处编码字符u'\ xc4':顺序号不在范围内(128)

>>> val 'DDRÄ'
>>> type(val) 类型的'str'


似乎函数的输出某种程度上是错误的。当ÅÄÖ参与进来时,它就返回data = u'DDR\xc4'而不是(按照我的意图)data = 'DDRAE'。关于什么可能导致此的任何建议?

Answers:


7

我经常处理一些特殊字符,例如您使用瑞典语(ä,ö,å),但也使用其他语言来表达其他语言,例如葡萄牙语和西班牙语(é,í,ú,ó等)。例如,我有数据,其中城市名称用简单的拉丁文写成,删除了所有重音,因此“哥德堡”变为“哥德堡”,“Åre”为“ Are”。为了执行联接并匹配数据,我必须将重音符号替换为基于英语拉丁字母的字符。

正如您首先在自己的答案中所显示的那样,我曾经这样做,但是这种逻辑很快变得难以维护。现在,我使用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模块的更多信息,网址为:删除python unicode字符串中的重音符号的最佳方法是什么?


我知道这可能有用,但是如果我们需要保持字符原样怎么办?我们可以做一些魔术来保留那些特殊字符吗?
Bogdan Mircea Stanciu

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,但没有帮助将其写入当前行(下一行)。[通过此修改来更新问题。]
Martin

您的意思是此行现在失败:prow.Typkod_U = val?有同样的错误吗?那么转换后的val值是多少?
mapoholic 2013年

我添加了一些新信息,包括新的错误消息。
马丁
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.