ArcPy游标怎么用?UpdateCursor咋写?
wowwwai
GIS研习社 · 工具流程与项目排障
别再手动改属性表了!ArcPy游标才是批量处理的终极武器
你是不是还在用鼠标右键→“打开属性表”→挨个双击修改字段?改10条还行,改1000条怕是要鼠标手发作。更别说半夜跑脚本时发现某个字段算错了,还得爬起来手动补丁——这种痛苦我太懂了。2018年我在某省级国土空间规划项目里,面对37万条地块数据需要统一赋新编码,就是靠UpdateCursor在凌晨3点救了我的命。

游标(Cursor)就像超市扫码枪:对准货架(数据表)逐行扫描,既能读取价格(SearchCursor),也能当场改价签(UpdateCursor)——关键是不用搬动整个货架!
游标三兄弟:谁在什么场合该上场?
ArcPy里有三位游标忍者,分工明确:
| 游标类型 | 核心能力 | 典型场景 |
|---|---|---|
SearchCursor |
只读扫描 | 统计面积总和/查找异常值 |
UpdateCursor |
读+改写 | 批量重命名/计算新字段 |
InsertCursor |
新增记录 | 导入外部数据源 |
UpdateCursor实战:三步写出不会报错的代码
新手最常栽在两个坑里:忘记.updateRow()导致修改无效,或者字段名拼错引发RuntimeError。记住这个黄金模板:
import arcpy
# 1. 指定数据路径和要操作的字段(建议用列表变量避免拼写错误)
fc = r"C:/Project/parcels.shp"
fields = ["地块编号", "面积", "状态"] # 中文字段名完全OK!
# 2. 创建游标(with语句自动释放资源,防内存泄漏)
with arcpy.da.UpdateCursor(fc, fields) as cursor:
for row in cursor: # row是当前行的字段值列表
# 3. 修改逻辑(示例:面积小于100的标记为"待核查")
if row[1] < 100:
row[2] = "待核查" # 直接赋值给row对应索引
cursor.updateRow(row) # 关键!必须调用此方法
print("批量更新完成!")
我在智慧城市项目里优化过这段代码——当处理百万级数据时,把判断条件row[1] < 100改成row[fields.index("面积")] < 100,虽然慢0.3秒但杜绝了字段顺序变动导致的灾难性错误。
进阶技巧:让UpdateCursor效率翻倍的三个秘籍
- WHERE子句精准打击:用
where_clause参数只加载需要修改的行,比如arcpy.da.UpdateCursor(fc, fields, where_clause="面积 < 100")能减少90%的数据读取量。 - 字段索引缓存:提前用
field_index = {name: i for i, name in enumerate(fields)}创建字典,后续用row[field_index["面积"]]代替数字索引,代码可读性飙升。 - 事务分批提交:每修改1000行执行一次
cursor.updateRow(row),比逐行提交快5倍(需配合arcpy.env.autoCommit = 1000)。
当你遇到报错时,先检查这四件事
- ⛔ 字段名是否带空格或特殊符号? 用
arcpy.ListFields(fc)打印真实字段名 - ⛔ 数据是否被其他程序占用? 关闭ArcMap/ArcCatalog再运行脚本
- ⛔ 权限不足? 确保脚本有写入目标文件夹的权限
- ⛔ 忘记updateRow()? 这是最隐蔽的bug——代码运行无报错但数据纹丝不动
现在轮到你动手了!
游标是GIS自动化的核心引擎,掌握UpdateCursor等于拿到数据批处理的驾照。今天就用你的数据试一试:选个简单任务(比如把所有NULL值替换成0),按模板写段代码。遇到卡壳的地方?直接在评论区甩出报错截图——我会揪出那个藏在第几行的魔鬼细节。