很多刚接触ArcGIS的人,拿到“按矢量范围统计栅格数据”这个需求时,第一反应就是“裁剪”,把栅格按矢量边界裁出来,然后打开属性表看统计结果。这个思路本身不算错,但一旦涉及的数据量变大、矢量范围变多、或者要统计的指标变复杂(比如众数、少数这类非参数指标),裁剪这条路就会走得非常痛苦。这篇文章我想直接聊一聊更正规、更高效的做法:用ArcGIS的分区统计工具,一次性把最大值、最小值、均值、中位数、众数、少数这些指标全部算出来,并且说清楚每个指标的适用场景和几个特别容易踩的坑。
1. 为什么“裁剪后再统计”是大多数人的第一反应,却往往不可靠
1.1 裁剪后统计的典型流程与潜在误差
先说最常见的做法。假设你现在手里有一个行政区的矢量边界,和一个DEM高程栅格,你想知道这个行政区内部的平均海拔是多少。常规操作是:用“按掩膜提取”把DEM裁出来,然后在ArcMap或ArcGIS Pro里打开裁剪后的栅格属性,Symbols选项卡里就会显示最小值、最大值、平均值、标准差这些基础统计值。
这个流程在一两个范围、单幅栅格时完全够用,但它有几个隐患。最典型的一个问题出在“边界处理”上:当矢量边界穿过一个像元时,ArcGIS的“按掩膜提取”默认会保留与掩膜相交的所有像元,也就是说,一个本来只占了边界很小一部分的像元,会被整个保留下来。如果这个像元面积很大(比如低分辨率栅格),或者边界特别曲折,统计出来的结果就会产生偏差——你本想要的是“这个多边形内部”的统计,实际算的却是“和这个多边形沾边”的统计。
另一个隐患是“多幅栅格、多个范围”的场景。比如你要统计全国各省份的夜间灯光数据均值,按裁剪思路,你得先把全国灯光栅格裁成34份(每个省级行政区一份),再逐份打开属性看统计值,最后手工录入Excel。这个过程不仅重复劳动量巨大,而且每裁剪一次就多出一份中间数据,磁盘空间不够的时候,ArcGIS还会频繁报“栅格构建失败”之类的错。如果中间某一步不小心把坐标系设置错了,所有统计结果都得推倒重来。
1.2 分区统计的真正逻辑:像元级聚合
分区统计(Zonal Statistics)解决的就是上面两个问题。它的核心逻辑完全不一样:矢量范围是“分区”(Zone),栅格是“被统计的值”(Value),工具会在每个分区内部,把该分区边界内所有栅格像元聚合为一个或多个统计指标,原理上根本不生成裁剪后的新栅格,只是“读取像元值进行计算”。
关于边界处理,正规的分区统计工具会采用“像元中心法”:只要像元的中心点落在分区内部,该像元就参与统计;中心点落在分区外就不参与。这听起来很简单,但在实际使用中对结果的影响非常大,尤其是小分区或者窄条形分区。比如一个宽度只有半个像元的狭长河流缓冲区,用裁剪法会纳入大量缓冲区外的陆成像元,而用像元中心法则可能恰好避开了这些陆成像元,统计出来的水质指标或植被指数差异极大。
所以我的建议是:只要你面对的不只是单个范围做一次性的“看一下”,而是要做严谨的空间统计分析,直接放弃“裁剪+属性表”的路径,改用分区统计工具。这是根子上的思路转变,也是整篇文章的基础。
2. 工具选型:一张表弄清楚Zonal Statistics族系的分工
ArcGIS里和分区统计相关的工具其实有好几个,很多人搞不清楚该用哪个,这里我先花点篇幅把它们的区别讲透,避免后面操作时选错工具。
2.1 核心工具对比
主要涉及三个工具,都在“Spatial Analyst工具箱 / 区域分析”和“Image Analyst工具箱”下:
| 工具名称 | 输出形式 | 单个分区的统计指标 | 适合场景 |
|---|---|---|---|
| “分区统计(Zonal Statistics)” | 栅格 | 单一指标(比如只输出均值) | 希望返回一个同分辨率栅格,后续还要做空间分析 |
| “分区统计为表(Zonal Statistics as Table)” | 属性表/表格 | 全部指标(最小值、最大值、均值、标准差、总和等) | 需要多个指标、需要做成报表或连接回矢量属性的场景 |
| “面积制表(Tabulate Area)” | 表格 | 各分区内各分类的面积或占比 | 土地利用、植被覆盖等分类栅格的面积汇总 |
如果你只是想“统计栅格数据的众数、最大值、均值、中位数、最小值、少数”,要用的就是第二个——分区统计为表。它一次能输出一整套描述统计量,然后你通过连接操作把统计结果关联回原始矢量要素,后续筛选、制图、出表都很方便。
2.2 为什么“分区统计为表”是首选
从功能上说,“分区统计为表”是这几个工具里最灵活的一个。它输出的.dbf或内存表里,每一行对应一个矢量要素(或者一个分区),每一列对应一个统计指标。默认你会得到:
- OBJECTID或分区字段
- 用于识别分区的字段值(比如行政区代码)
- 每个分区的像元数量(COUNT)
- 面积(AREA)
- 最小值(MIN)
- 最大值(MAX)
- 平均值(MEAN)
- 标准差(STD)
- 总和(SUM)
这里有个细节值得留意:在中位数(MEDIAN)和众数(MAJORITY)这两个指标上,不同版本ArcGIS的表现略有不同。ArcGIS 10.x和Pro在“分区统计为表”工具界面里,可以从“统计类型”下拉框里勾选ALL,一次性输出包括中位数、众数、少数在内的全部指标;但如果你是直接调用arcpy代码,就需要显式指定统计类型为MEDIAN或MAJORITY,否则默认只有基础的一些统计量。
我见过不少人在这里踩坑:用ArcPy跑完脚本后表格里只有MIN、MAX、MEAN、STD,找不到想要的中位数和众数,怀疑是软件版本问题,其实只是脚本里没写统计类型。这点后面实操环节我会再强调。
3. 核心实操:Zonal Statistics as Table的完整参数详解
3.1 输入数据的准备
开始操作前,先确认三个前置条件:
第一,矢量数据最好是面要素。虽然工具也接受点要素和线要素,但点、线的“区域”概念比较特殊——工具会以点线周边默认范围为一个小的统计区域,实际操作中很容易出现“分区太小导致没有像元落入”的情况。所以如果不是特殊需求,建议用面要素。
第二,栅格和矢量的空间参考尽量保持一致。工具本身会自动做投影转换,但当两个数据的坐标系差异较大(比如一个是地理坐标系WGS84,一个是投影坐标系UTM),ArcGIS会先把栅格重新采样或转换到矢量的坐标系里,这个过程会多一道计算,而且可能引入重采样误差。最稳妥的做法是在操作前把矢量要素投影到和栅格一致的坐标系,或者统一投影到一个适合你研究区域的投影坐标系里。
第三,栅格数据类型最好是整型或浮点型都能处理,但如果你想统计众数和少数,就要稍微留意一下数据类型。众数的本质是“出现频率最高的像元值”,如果你是浮点型的高程或温度栅格,每一个像元值都几乎是唯一的,众数统计出来的结果意义不大,顶多就是某一个“刚好出现两次”的值。这一点不是工具的问题,而是统计指标本身的适用性问题,后面在“众数与少数”那一节我会专门展开。
3.2 关键参数设置与选择逻辑
打开“分区统计为表”工具(Analysis工具箱或Spatial Analyst工具箱下都可以找到),界面其实很简洁,关键参数如下:
- “输入栅格数据或要素区域数据(Input zone data)”:选你的矢量面要素。
- “区域字段(Zone field)”:选一个能唯一标识每个分区的字段,比如行政区代码、地块编号。这里要特别提醒,千万不要选那种多个要素共用相同值的字段,否则ArcGIS会把相同值的所有要素合并为一个分区来统计。比如你按“地类名称”这个字段去分区,那所有水田会合并统计,所有旱地会合并统计,而不是按每个图斑单独统计。
- “输入值栅格(Input value raster)”:选你要统计的那个栅格。
- “输出表(Output table)”:设置输出路径,可以输出成dBASE表、地理数据库表,也可以直接输出到一个内存表。
- “统计类型(Statistics type)”:这里最关键。默认可能是“ALL”(输出全部统计量),也可能是“MIN_MAX_MEAN”之类的简化版本,具体看你用的工具版本。我们需要在这里勾选:MINIMUM、MAXIMUM、MEAN、MEDIAN、MAJORITY、MINORITY,确保输出表里同时包含这六个指标。
有一个“忽略NoData”的选项默认是勾选状态,这个一般保持默认就好。它的意思是,如果某个像元是NoData,这个像元将不参与任何统计计算。后面我会讲一个特殊情况——当你的NoData可以作为“0值”参与统计时,应该怎么处理。
3.3 中位数需要额外两步处理的原因
这里单独把中位数拿出来说,是因为它有一个很细节但容易忽略的问题。
在ArcGIS 10.x和较早的ArcGIS Pro版本中,“分区统计为表”这一工具的中位数结果,并不是直接输出在最终表格里的,而是需要通过“分区统计”工具(输出栅格版本)的“中位数”选项,或者通过其他方式间接获取。在较新的Pro 3.x版本里,中位数已经被直接集成到“分区统计为表”的ALL统计类型里了。但如果你还在用10.x,或者是用旧脚本处理,可能会发现无论怎么勾选,输出表里都没有MEDIAN这一列。
遇到这种情况,我的建议是直接用一个新的工具组合:使用“分区统计(Zonal Statistics)”并把统计类型设为“中位数”,输出一个中位数栅格,然后用“提取多值到点”或“分区统计为表”再次合作——听起来有点绕,但实际效果很好。也可以用“以表格显示分区统计(Zonal Statistics as Table)”后再用“连接字段”方式和“提取多值到点”的结果做二次关联。
还有一个更稳妥的办法,直接上ArcPy脚本来处理。用arcpy.sa.ZonalStatisticsAsTable,在调用时把统计类型写成“MEDIAN”,它会生成单独的中位数统计表,再和其他指标的统计表按分区字段做连接。这样不管软件版本怎么变,逻辑都不会出错。
我实测下来,ArcGIS Pro 3.x用界面操作最为省心,ArcMap 10.x建议直接用ArcPy指定统计类型。
4. 容易忽略但很实用的统计量:众数与少数
4.1 众数的意义及应用场景
众数(MAJORITY)在ArcGIS里的定义是:某个分区内出现频率最高的像元值。如果你在处理分类栅格,比如土地利用类型、植被类型、土壤类型,众数就是“这个区域里最常见的类别”,这个信息往往比均值更有决策价值。
举个例子。你拿着一个县级行政边界去统计全国30米土地利用数据,想快速判断“这个县的主导地类是什么”。用平均值?完全没概念,因为这是分类数据,不是连续数值。用众数,直接就能告诉你:“这个县大约60%的面积是耕地”。这对于做土地利用格局分析、县域发展评估都极其直观。
另一个典型场景是森林资源调查。面对一个林班(小班)边界,你手里有一幅树种分布栅格(比如1代表马尾松、2代表杉木、3代表阔叶混交),想快速知道这个林班的主导树种,用众数是最直接的办法——它直接回答“这里最常见的树是什么”。如果你用最大值或者均值,得到的“1.6”根本没法解释。
4.2 少数(MINORITY)的用途,多数人没用过
少数(MINORITY)是与之对称的指标:某个分区内出现频率最低的像元值。很多人看到这个指标会愣一下,觉得“出现频率最低的值有什么用?”其实在特定场景下它非常有用。
比如做生态保护时,你有一个自然保护区的边界,叠加一幅植被类型图,想知道保护区内“最稀缺的植被类型是什么”。这个信息对于制定保护优先级、开展珍稀植被空间识别很有参考价值——众数告诉你主体,少数告诉你短板。
又比如做土壤污染评价。你在一个矿区的矢量范围内统计土壤重金属污染等级栅格(分级编码1-5,5为重度污染),少数指标会告诉你“这个区域里污染级别出现得最少的那个级别是什么”。如果少数恰好是5,反过来说明污染级别5的分布很小,污染面积主要集中在较低级别;如果少数是1而众数是4或5,说明这个区域几乎没有“清洁”的像元,污染已经到了全覆盖的程度。两种解释方向不同,但少数这个指标都能帮你在看到均值之外多一个判读维度。
在使用少数时要注意:当分区内像元数量很大但类别很少时(比如只有两个类别),少数指标实际上是“另一类”,它和众数互为补充,分析时别把它当成“某一种罕见小类”就行了。
4.3 一个土地利用分类的实战案例
为了把这部分讲得更落一点,我描述一个我自己做过的场景。
有一个县域的土地利用数据,是30米分辨率的分类栅格,编码规则大致是:10耕地、20林地、30草地、40水域、50建设用地、60未利用地。上级要求我们做一个“县域内地类结构评估”,需要给全县19个乡镇分别输出一张“地类占比表”,并标注每个乡镇的主导地类(地类代码众数)。
我一开始想到用面积制表(Tabulate Area),它能输出每个乡镇里每个地类的面积,排序后取最大值就是主导地类了。但真正的实施中,我同时还想知道“各乡镇里最罕见的地类是什么”、“地类多样性高不高”,面积制表给出的信息还不够直观。
最终方案是:用“分区统计为表”,把统计类型设为ALL,一次得到每个乡镇的MAJORITY(主导地类)和MINORITY(最罕见地类),再用“面积制表”补充各类型面积比例。整个过程十分钟内全部完成,直接输出成Excel,后续画柱状图、拼图出报告都特别方便。
如果你也遇到类似“分类数据+多分区”的情况,请记住优先用众数和少数,而不是只想着面积制表——两者的输出口径不一样,众数直接给你“常见类型值”,而面积制表只会给你各类型面积,还得你自己再排序。
5. 实操中的高频坑与排查链路
5.1 投影不一致导致的面积和统计偏差
我见过最典型的错误是这样的:矢量数据是正确的UTM投影坐标系,栅格数据是地理坐标系WGS84,分辨率写的是0.01度。工具能跑通,也不会报错,但出来的结果却和“用裁剪后属性表统计”的结果对不上。
原因在于,ArcGIS在“分区统计为表”的计算中会做动态投影转换。栅格值的读取是以矢量坐标为准的,当栅格是经纬度坐标、矢量是投影坐标时,一个像元的真实“覆盖范围”在投影变换后会发生变形,尤其在高纬度地区,经纬度0.01度对应的地面距离会被拉长。这个变形会导致某些分区边缘的像元归属判断出错。
所以操作前请务必养成一个好习惯:在ArcToolbox里先用“投影(Project)”工具把矢量要素投影到与栅格一直的坐标系,再用“投影栅格(Project Raster)”把栅格投影到适合分析的投影坐标系,最后开始统计。如果两个数据坐标系来源不同却“看起来大概差得不远”,千万别图省事直接跑。
5.2 NoData值是否参与统计
这个坑特别隐蔽。默认情况下,分区统计工具会把NoData像元忽略掉。这在多数场景下是符合预期的——比如你统计NDVI,云遮挡区域全是NoData,你当然不希望这些区域按0值参与平均。
但有些时候你手头的数据里,NoData代表的是“真实存在的0”。比如某地区的降水栅格里,NoData可能并不是没有数据,而是“无降水记录”,实际应该按0处理;或者某个生态因子栅格的NoData代表“该区域无植被覆盖”,实际应该参与统计。这时要怎么做?
我的经验是:先用“栅格计算器”或“复制栅格”工具,把NoData替换为0或某个特定常数,再送入分区统计。替换公式很简单:
# 在ArcGIS栅格计算器中,将NoData替换为0 Con(IsNull("your_raster"), 0, "your_raster")然后再做分区统计,得到的结果才是你真正想要的“包含零值”的计算结果。如果是用ArcPy,代码大概是:
import arcpy from arcpy.sa import * out_raster = Con(IsNull(your_raster), 0, your_raster) out_table = ZonalStatisticsAsTable(zone_vector, zone_field, out_raster, output_table, "DATA", "ALL")判断“要不要替换NoData为0”的标准很简单:问问自己,在你这个业务场景里,这个位置“没有数值”到底是意味着“没有这个现象”,还是“值太低没检测到”。前者可以替换成0或忽略,后者如果替换成0会严重拉低均值,宁可忽略也别强行赋值。
5.3 分区太小导致COUNT为0或统计结果为空
当你的矢量分区非常小(比如面积只有几百平方米),而栅格分辨率又很粗(比如250米分辨率的MODIS数据),可能会出现一个分区内没有任何像元中心落入的情况。此时输出表里该分区的COUNT为0,所有统计指标为空。
这种情况怎么处理?
第一,你可以用“分区统计为表”的“忽略NoData”选项也无济于事,因为问题不是NoData而是根本没有像元。第二,工具界面里有一个“作为几何面积(As geometry)”的选项,勾选后ArcGIS会尝试把分区面积作为权重去估算统计值,但由于没有像元落入,这个选项基本也救不回来。第三,最根本的解法是把栅格重采样到更小的像元(或用双线性/最邻近法新建一个更高分辨率的栅格),确保小分区至少能覆盖到几个像元中心。
这里提供两个思路:一是用“重采样(Resample)”把栅格像元改到足够小;二是换个分析尺度——如果你的分区本身就特别小,但栅格数据分辨率是几十公里级别,那统计结果本身就没什么统计学意义,不如把多个邻近小分区合并后再统计。
5.4 属性表连接后字段类型和记录顺序问题
“分区统计为表”输出后,通常要把表格连接回原始矢量要素,许多人在这一步遇到两个小毛病。
一个是字段类型。输出表里的COUNT和AREA字段类型是双精度浮点,而MODE和MEDIAN这类指标可能是双精度也可能是长整型,要看源栅格类型。连接回矢量属性表后,如果你用“字段计算器”做后续处理,比如加总某个字段,可能会因为字段类型不匹配导致计算失败或被四舍五入。建议连接前先确认源栅格类型,如果栅格是浮点型,那么统计结果里的中位数、众数都可能是小数,但你绝不能拿小数去“查地类编码”——地类编码必须是整数。处理办法是用“取整”字段计算把统计值取整。
另一个是记录顺序。很多人在连接后没有对磁盘上的要素类做“导出”,连接只是“视图层”的临时关联,如果你在ArcMap或ArcGIS Pro里看着连接结果觉得没问题,就直接拿去出图,没问题;但如果你要把它作为新的数据源供外部程序使用,一定要“导出要素”生成新文件,否则连接字段不会被永久保存。
6. 让结果更稳健:中位数与异常值处理的进阶思路
6.1 为什么在中位数和均值之间要留个心眼
在实际项目里,均值(MEAN)是最常用的统计量,但它也是被误用得最严重的统计量。均值的本质是把分区内所有像元值加起来除以总数,它对极端值非常敏感。假设你在统计某个流域的PM2.5浓度栅格,这个流域里99%区域的浓度都在30-50之间,但边缘正好有一个厂区的像元值是500,那么算出来的均值可能被拉高到60甚至更高,你觉得“这个流域污染挺严重”,但实际上绝大多数区域并没有那么糟。
这是一种典型的“均值失真”。中位数就没有这个问题:把所有像元值按顺序排列,取中间位置的那个值。它只关心“排在最中间的那个像元是多少”,即便有极端值存在,只要它排在两端,就不会影响中位数。所以做环境质量评估、土壤重金属污染评价、房价和人口收入类数据统计时,我强烈建议你同时输出均值和中间位数。如果两者差异明显,说明你这份数据里大概率存在极端值“干预”了整体判断,需要进一步排查。
6.2 结合栅格计算器和分区统计实现稳健统计的实战思路
既然中位数对极端值不敏感,那有没有办法直接把这种“稳健思想”用到流域评价、区域对比里去?有,而且不难,核心就是把“先统计再比较”的思路,替换为“先筛选再比较”。
我用一个土壤污染评价的案例来说明。假设你有一幅土壤重金属铜含量的连续栅格,背景是某个县几十个村庄的边界,你想判断哪些村庄的铜污染属于“严重且普遍”。
第一步,用栅格计算器,把所有像元值超过某个阈值(比如国家风险筛选值100mg/kg)的地方置为1,其余置为0:
Con("cu_raster" > 100, 1, 0)第二步,用“分区统计为表”统计每个村庄的均值(也就是污染超标像元占比),再统计“超标像元数”,这样你得到的不仅仅是一个全村的平均污染值,而是“超标范围有多大”的直接证据。
第三步,你再结合众数(MAJORITY)来看:如果MAJORITY是1,说明该村大多数像元都是超标的,污染“普遍”;如果MAJORITY是0,说明超标是零星分布,虽然均值可能不低,但污染并不普遍。这两种结论在治理优先级上完全不同。
这种“先用栅格计算器做逻辑判断,再叠加分区统计做汇总”的思路,比单纯把均值和中位数拿出来对比更贴近实战,因为它在统计之前就已经把“业务规则”写进像素了。像这种处理,我建议你练熟Con、IsNull、ZonalStatisticsAsTable三个工具的组合,在做很多生态、环境、土地利用评价时都会反复用到。
6.3 分位数、累积百分比等衍生指标的自定义思路
如果中位数还不够,你还想要更细的分位数(比如第25百分位数、第90百分位数),ArcGIS自带的分区统计工具是不直接支持“自定义百分位数”的,但你可以借助分位数栅格的思路来实现。
一个常规操作是:先用“直方图”工具或用“提取分析”把分区内像元值全部提取出来,在表格或外部软件里算分位数,再汇总回分区。不过这种方法在要素多、像元多的时候计算量比较大,跑起来比较慢。
另一种思路是用“条件分析”配合“分区统计”:比如你想知道某个区域里超过第90百分位数的高值像元分布,可以先把全局栅格进行“百分比阈值化”,再用Con函数提出高值区,最后用面积制表来统计高值区的面积和占比。这样做虽然不给出精确的第90百分位数数值,但把“哪些区域属于高值区”“高值区面积多大”这两个业务问题回答得很清楚。
总之,ArcGIS的分区统计工具家族并不是“只有那么几个统计量的死板工具”,它是可以借助栅格计算器、Con条件函数和其他空间分析工具组合出很多自定义指标的。关键在于你对自己业务逻辑的建模是否清晰——是先分区再算?还是先筛选再分区统计?这两条路径的适用范围完全不同,建议你在动手前先画个逻辑草图,再开工具界面。
7. 一个完整案例:全流程实操演示与结果解读
为了让前面那些概念落得更实,这里给一个可以照着做的完整案例。
假设你手里有一个省内的“生态功能区”矢量文件,几十个区块,另一个是30米分辨率的“植被覆盖度”栅格(0-100之间的整数)。你想知道每个功能区内植被覆盖度的众数、最大值、均值、中位数、最小值、少数,并且想在ArcGIS里把结果做成一张专题图。
步骤一:在ArcGIS Pro的目录窗格里,右键你的栅格数据,确认它的“源”中的像元大小和坐标系。如果坐标系不是投影坐标系,就先用“投影栅格”重投影(比如用Albers等积投影)。同时用“投影”工具把你矢量数据投影过来,保证两者坐标系一致。
步骤二:打开“地理处理”窗格,搜索“Zonal Statistics as Table”,在弹出的工具面板中:
- 输入区域数据:选择面要素(生态功能区)
- 区域字段:选FID或“区名”这种唯一字段
- 输入值栅格:选择植被覆盖度栅格
- 输出表:选择输出路径,命名为“eco_veg_stats”
- 统计类型:勾选ALL,或者手动把MINIMUM、MAXIMUM、MEAN、MEDIAN、MAJORITY、MINORITY全部选上
- 运行
步骤三:打开输出的属性表,你会看到类似下面的结构:
| 区域名 | COUNT | AREA | MIN | MAX | MEAN | MEDIAN | MAJORITY | MINORITY |
|---|---|---|---|---|---|---|---|---|
| A功能区 | 128500 | 115650000 | 12 | 98 | 63.2 | 66 | 71 | 23 |
| B功能区 | 83000 | 74700000 | 8 | 95 | 51.6 | 55 | 55 | 14 |
这个表里信息量已经很大了。B功能区的MAJORITY和MEDIAN非常接近,说明数据分布相对稳定;A功能区的MINORITY是23,说明功能区内存在少量低植被覆盖度的地方,可能是裸地或建设用地;如果A功能区名义是“水源涵养区”,这个数字就值得再叠加上“查询高覆盖度(≥80)面积占比”来做深入分析。
步骤四:把表连接回原始矢量,在图层属性中使用“连接和关联”,按区名字段连接。然后可以符号化用MEAN字段做渐变渲染,也可以用MAJORITY字段做分类渲染,一个“生态功能区植被现状”专题图轻松搞定。
这个小案例的核心思路和前面是一致的:先用分区统计把复杂栅格信息浓缩为一个表,再把表作为属性连接回矢量要素,完成“栅格统计结果空间化表达”。后面不管是做报表、做图,还是做多维评估,都是从这个表出发,不会再去重算栅格了。
8. 最后的几条经验与建议
写到这里,该讲的原理和操作都讲得差不多了,最后分享几条我从实际项目里摸出来的经验,或许能让你少走点弯路。
第一,分区统计的结果依赖数据质量,比依赖工具设置还重。如果你输入的栅格存在大量NoData、传感器坏线、异常值,不管你统计类型选得多全,出来的表都是不可信的。所以做统计前,先把栅格的“栅格属性”打开,看一眼直方图(Histogram),必要时先做一波异常值剔除或平滑处理,再喂给分区统计。
第二,中位数与众数这类非参数指标,在ArcGIS里能直接算,但你要会解读。很多人拿到表后只会看MEAN,把MAJORITY当成“排序第一个的值”,这是对众数的误读。上面说过,众数是出现频率最高的值,不是最大或最小的值。如果拿众数去排序找极值,结论会完全反掉。
第三,批量处理时建议直接写Python脚本,不要依赖工具界面。一次统计100个分区,工具界面点击操作还凑合;如果统计几千个分区、多期遥感影像,用arcpy循环是最快最稳的方式。而且脚本最大的好处是可以把“替换NoData→统计→导出报表”的流程固定下来,下次换一批数据直接改路径就可以运行。附上我常用的精简脚本模板,供你参考:
import arcpy from arcpy.sa import * arcpy.env.workspace = r"D:\your_data" arcpy.env.overwriteOutput = True arcpy.CheckOutExtension("Spatial") zone_fc = "eco_regions.shp" zone_field = "RegionID" value_raster = "veg_cover.tif" out_table = "eco_veg_stats.dbf" # 统计全部指标 out_zstat = ZonalStatisticsAsTable(zone_fc, zone_field, value_raster, out_table, "DATA", "ALL") print("Zonal statistics completed: " + out_table)这里把NoData替换为0或其他值的处理你可以根据实际需要插入,比如在调用ZonalStatisticsAsTable之前先走一遍Con函数,或者直接把Con后的结果作为value_raster传入。
第四,统计结果在做对比分析时,一定要连同COUNT列一起看。COUNT代表每个分区里实际参与统计的像元数量,当两个分区的COUNT差异很大时,直接比较它们的MAX或MIN意义有限。比如A分区有10000个像元,B分区只有50个像元,A的最大值可能是被边缘的单一高值噪声拉起来的,而B的最大值相对稳定。在写结论之前,先在表里把COUNT和AREA列扫一眼,做到心里有数。
分区统计这个事情,说难不难,说简单也不简单,关键是对工具逻辑的理解和对数据本身的敬畏。你只要先把“裁剪后看属性”的思路丢掉,换成“分区聚合”的空间统计思维,再掌握好本文说的这几个关键参数和坑,以后碰到这类需求基本可以做到又快又稳。希望这篇经验对你有实际帮助。