ArcPy实用教程(含arcpy select by attribute详细解析)
很多团队在做 ArcGIS 数据处理时,最费时的环节往往是“点开工具、写筛选条件、导出结果”的重复操作。作为 GIS 研发与教学的一员,我常被问到:怎样把这些“按属性筛选”的流程写成可靠的脚本,既保证结果一致,又能应对不同数据源的 SQL 差异?本指南将带你一步步搭建一个可复用、可扩展的方案。
是什么:ArcPy 与基于属性的选择
ArcPy 是 ArcGIS 的 Python 接口,核心是把地理处理工具以函数形式暴露出来,便于自动化。基于属性的选择本质上就是向数据源发送 SQL 表达式,得到满足条件的记录(要素)。在 ArcPy 中,常用的是 arcpy.management.SelectLayerByAttribute:
- 对象类型:操作对象是“图层或表视图”(layer/view),而非直接对要素类。
- 选择方式:支持 NEW_SELECTION、ADD_TO_SELECTION、REMOVE_FROM_SELECTION、SUBSET_SELECTION、SWITCH_SELECTION 等。
- 输出管理:选择集可直接用于后续工具(如 CopyFeatures)或继续叠加空间选择。
要点:先把要素类变成“图层”,再在图层上做选择;图层承载“选择集”这一状态。
为什么:脚本化的价值
- 可重复与可追溯:同一脚本在不同地区或时间段复用,保证标准一致。
- 性能更优:让数据库/数据源替你筛选,避免 Python 逐行循环。
- 参数化与集成:轻松嵌入批处理、调度和模型构建器,形成生产流水线。
怎么做:最小可行流程
- 准备环境与工作空间。
- 将要素类构造成图层。
- 编写 SQL 表达式(使用 AddFieldDelimiters 防止字段名兼容性问题)。
- 执行选择并导出结果。
# 基础示例:价值>100000 且 分区=R1 的地块
import arcpy
arcpy.env.workspace = r"C:GISdemo.gdb"
arcpy.env.overwriteOutput = True
fc = "Parcels"
lyr = "Parcels_lyr"
# 确保图层存在的是最新状态
if arcpy.Exists(lyr):
arcpy.management.Delete(lyr)
arcpy.management.MakeFeatureLayer(fc, lyr)
fld_land = arcpy.AddFieldDelimiters(fc, "LAND_VALUE")
fld_zone = arcpy.AddFieldDelimiters(fc, "ZONING")
where = f"{fld_land} > 100000 AND {fld_zone} = 'R1'"
arcpy.management.SelectLayerByAttribute(lyr, "NEW_SELECTION", where)
arcpy.management.CopyFeatures(lyr, "Parcels_R1_HighValue")
print(arcpy.GetCount_management(lyr)[0], "features selected")
提示:where 子句中,文本值要用单引号括起;数值不需要引号。
SQL 表达式要点与常见坑
- 字段定界符:不同数据源对字段名的定界方式不同(如双引号、方括号)。统一用 arcpy.AddFieldDelimiters(dataset, field) 生成,避免手写。
- 通配符:大多数数据源使用 %(多字符)、_(单字符)。个人地理数据库(.mdb)使用 * 与 ?。
- NULL:用 IS NULL、IS NOT NULL;不要用 = NULL。
- 日期:文件/企业地理数据库常用 date 'YYYY-MM-DD HH:MM:SS';个人地理数据库常用 #YYYY-MM-DD#;企业库需遵循各自 SQL 方言。
- 大小写:是否区分大小写取决于数据源与区域设置;必要时统一大小写或用函数处理(企业库)。
- 精度:浮点比较尽量使用范围(如 BETWEEN 或差值阈值),避免直接等于比较。
数据源 | 字段定界符 | LIKE 通配 | 日期字面量示例 |
---|---|---|---|
文件地理数据库 (.gdb) | 通常为双引号(由 AddFieldDelimiters 处理) | % / _ | date '2023-01-01' |
企业地理数据库 | 遵循底层 DBMS(建议用 AddFieldDelimiters) | % / _ | 依 DBMS(如 Oracle: DATE '2023-01-01') |
个人地理数据库 (.mdb) | [](由 AddFieldDelimiters 处理) | * / ? | #2023-01-01# |
Shapefile (.shp) | 由 AddFieldDelimiters 处理 | % / _ | date '2023-01-01' |
# 日期与 NULL 示例
fc = "Inspections"
lyr = "Inspections_lyr"
arcpy.management.MakeFeatureLayer(fc, lyr)
d_fld = arcpy.AddFieldDelimiters(fc, "INSPECT_DATE")
s_fld = arcpy.AddFieldDelimiters(fc, "STATUS")
# 选择 2023 年内且状态非空的记录(文件地理数据库语法)
where = (
f"{d_fld} >= date '2023-01-01 00:00:00' AND "
f"{d_fld} < date '2024-01-01 00:00:00' AND "
f"{s_fld} IS NOT NULL"
)
arcpy.management.SelectLayerByAttribute(lyr, "NEW_SELECTION", where)
选择类型与组合策略
- NEW_SELECTION:首次选择或重置选择集。
- SUBSET_SELECTION:在已有选择集内进一步筛选。
- ADD_TO_SELECTION / REMOVE_FROM_SELECTION:并集或差集式操作。
- SWITCH_SELECTION:反选,快速得到补集。
# 先按属性,再叠加空间关系进行“组合筛选”
roads = "Roads"
city = "CityBoundary"
rlyr = "Roads_lyr"
arcpy.management.MakeFeatureLayer(roads, rlyr)
# 1) 仅选主干道
fld = arcpy.AddFieldDelimiters(roads, "CLASS")
arcpy.management.SelectLayerByAttribute(rlyr, "NEW_SELECTION", f"{fld} = 'Primary'")
# 2) 再筛选位于城市边界内的主干道
arcpy.management.SelectLayerByLocation(
rlyr, "INTERSECT", city, selection_type="SUBSET_SELECTION"
)
# 3) 导出
arcpy.management.CopyFeatures(rlyr, "PrimaryRoads_InCity")
性能优化与工程实践
- 索引优先:对高频过滤字段建立属性索引;显著提升选择速度。
- 一次建层,多次复用:MakeFeatureLayer 创建一次,后续多次选择,避免重复开销。
- 充分用 SQL:能在 where 子句完成的过滤,不要用 Python 循环逐行判断。
- 内存工作空间:临时结果可用 in_memory(注意容量与生命周期)。
- 选择后直接串联:将选择集直接传给 CopyFeatures、CalculateField 等,减少磁盘 I/O。
- 批处理:把 where 子句参数化,驱动多地区/多时间段自动跑批。
# 参数化批处理(简化示例)
def export_by_zone(workspace, fc, zone_value, out_name):
arcpy.env.workspace = workspace
lyr = "tmp_lyr"
if arcpy.Exists(lyr):
arcpy.management.Delete(lyr)
arcpy.management.MakeFeatureLayer(fc, lyr)
z = arcpy.AddFieldDelimiters(fc, "ZONING")
where = f"{z} = '{zone_value}'"
arcpy.management.SelectLayerByAttribute(lyr, "NEW_SELECTION", where)
arcpy.management.CopyFeatures(lyr, out_name)
return int(arcpy.management.GetCount(lyr)[0])
# 批量导出多个分区
for z in ["R1", "R2", "C1"]:
n = export_by_zone(r"C:GISdemo.gdb", "Parcels", z, f"Parcels_{z}")
print(z, ":", n)
与 Data Access 游标的配合
当仅需读取统计或做轻量计算时,arcpy.da 游标支持 where_clause,能不创建图层而直接过滤。
# 使用 SearchCursor 按属性过滤后统计数量
fc = r"C:GISdemo.gdbParcels"
fld_val = arcpy.AddFieldDelimiters(fc, "LAND_VALUE")
where = f"{fld_val} > 100000"
cnt = 0
with arcpy.da.SearchCursor(fc, ["OID@", "LAND_VALUE"], where_clause=where) as cur:
for oid, val in cur:
cnt += 1
print("count:", cnt)
选择集与游标并不冲突:前者适合串联地理处理工具;后者适合轻量读写与自定义逻辑。
典型案例与可复用片段
# 1) 模糊匹配:名称以 'San' 开头(% 为任意多字符)
fc = "Counties"; lyr = "Counties_lyr"
arcpy.management.MakeFeatureLayer(fc, lyr)
name_f = arcpy.AddFieldDelimiters(fc, "NAME")
arcpy.management.SelectLayerByAttribute(lyr, "NEW_SELECTION", f"{name_f} LIKE 'San%'")
arcpy.management.CopyFeatures(lyr, "Counties_SanPrefix")
# 2) 复合条件:人口>10万 且 面积在[500, 2000]
pop_f = arcpy.AddFieldDelimiters(fc, "POP")
area_f = arcpy.AddFieldDelimiters(fc, "AREA_KM2")
where = f"{pop_f} > 100000 AND {area_f} BETWEEN 500 AND 2000"
arcpy.management.SelectLayerByAttribute(lyr, "NEW_SELECTION", where)
# 3) 处理空值:仅保留代码不为空的记录
code_f = arcpy.AddFieldDelimiters(fc, "CODE")
arcpy.management.SelectLayerByAttribute(lyr, "SUBSET_SELECTION", f"{code_f} IS NOT NULL")
数据源 → MakeFeatureLayer → SelectLayerByAttribute → (可选)SelectLayerByLocation → CopyFeatures/统计
结语
本文从“是什么/为什么”切入,落到“怎么做”的操作层:用图层承载选择集,用 AddFieldDelimiters 适配不同数据源方言,用标准 SQL 处理字符串、日期与 NULL,选择类型组合实现复杂筛选,并配合游标、索引与内存工作空间优化性能。掌握这些要点,你就能把任何一次性的手工筛选变为稳定的自动化构件。
你的数据源类型和典型 where 子句有哪些?欢迎把代表性的表达式与难点留言交流。我是 Dr.gis,也欢迎关注 GIS研习社(gisyxs.com) 的进阶实战内容。
参考文献
- ArcGIS Pro: Select Layer By Attribute (Data Management)
- ArcGIS Pro: SQL reference for query expressions used in ArcGIS
- ArcPy: AddFieldDelimiters
- ArcPy Data Access: SearchCursor
- ArcGIS Pro: Make Feature Layer
- ArcGIS Pro: Select Layer By Location
相关文章
-
gis python 开发入门全解析,gis Python新手指南 2025-09-06 12:13:26
-
gis python开发者必看,gis Python基础入门全解析 2025-09-06 12:13:25
-
gis Python入门指南,从解析gis python基础知识谈起 2025-09-06 12:13:24
-
gis Python入门指南,从解析Gis python库开始 2025-09-06 12:13:23
-
ArcPy实用教程,详解arcpy describe的核心用法 2025-09-02 15:03:03
-
ArcPy入门学习指南(含:arcpy documentation的详细解答) 2025-09-02 15:03:02
-
ArcPy入门学习指南(含:arcpy make feature layer的详细解答) 2025-09-02 15:03:01
-
ArcPy实用技巧解析(含arcpy export features详细讲解) 2025-09-02 15:03:00
-
ArcPy入门学习指南(含:arcpy python的详细解答) 2025-09-02 15:02:59
-
ArcPy入门详解(含arcpy map核心应用解析) 2025-09-02 15:02:59
-
ArcPy入门全指南(附arcpy reference详细解析) 2025-09-02 15:02:58
-
ArcPy核心用法详解(含arcpy copy features实战教程) 2025-09-01 11:21:12
-
ArcPy核心教程,详解arcpy copy features实用方法 2025-09-01 11:21:11
-
ArcPy入门详解(含arcpy基础知识与实用技巧) 2025-09-01 11:21:11
-
ArcPy实用技巧详解(含arcpy spatial join操作方法) 2025-09-01 11:21:10
-
ArcPy入门教程(含arcpy documentation详细解析) 2025-09-01 11:21:09
-
ArcPy基础教程,详解arcpy export features的实现方法 2025-09-01 11:21:08
-
ArcPy实用教程(含arcpy list fields的详细解析) 2025-09-01 11:21:07
-
ArcPy教程详解(含arcpy select by attribute实用方法) 2025-09-01 11:21:06
-
ArcPy入门详解(含arcpy make feature layer实用教程) 2025-09-01 11:21:06
热门标签
最新资讯
2025-09-27 08:48:41
2025-09-27 08:36:27
2025-09-27 08:34:46
2025-09-27 08:30:03
2025-09-27 08:25:45
2025-09-27 07:47:30
2025-09-27 07:35:01
2025-09-27 07:12:39
2025-09-27 06:45:53
2025-09-27 06:11:56