1992-2022年各省夜间灯光数据:从Excel面板到Shapefile空间分析全流程指南 夜间灯光数据在区域经济研究里算是个老资历的指标了但真正把它用顺手的人并不多。我最早接触这类数据是为了做一组省域发展水平的横向对比当时手头只有统计年鉴里的GDP和人口指标之间高度共线跑出来的结果自己都不太信。后来换成夜间灯光总量和均值做代理变量很多原本模糊的省际差异一下子就清晰了。这份1992-2022年各省夜间灯光数据覆盖三十一年、横跨全部省级单元同时提供Excel和Shapefile两种格式本质上解决的是长时间序列、空间可比、开箱即用这三个痛点。它适合做区域经济、城镇化、能源消耗、环境压力等方向的研究者也适合需要给面板数据找一个稳定代理变量的分析人员。下面我按自己实际使用这套数据的顺序把格式选择、指标口径、时间序列处理、空间分析和常见坑逐一拆开讲尽量让你拿到文件就能直接上手而不是先花两天搞清楚字段含义。1. 先搞清楚这份数据到底装了什么拿到一个压缩包最忌讳的就是直接双击打开Excel看一眼就开始跑回归。夜间灯光数据的价值密度很高但它的结构比普通统计数据复杂先花十分钟摸清家底后面能省掉大量返工。1.1 Excel与Shapefile的分工不是简单的重复很多人以为Excel和shp只是同一份数据的两种导出格式随便挑一个用就行。实际用下来两者的定位差别很大。Excel版的核心价值在于面板结构每一行通常对应省份-年份的组合列里放灯光总量、平均亮度、灯光面积等汇总指标直接可以喂给统计软件做固定效应、随机效应或者动态面板。它的优势是省去了空间聚合这一步你不需要懂GIS就能用。Shapefile版的核心价值在于空间粒度它保留的是栅格或矢量化的灯光分布能让你做空间自相关、核密度、热点分析或者把灯光值提取到自定义的行政区划、流域、城市群边界上。换句话说Excel回答的是这个省这一年有多亮shp回答的是这个省这一年亮在哪里。我的建议是两者都留着。做计量用Excel做空间格局图或者需要重新划分空间单元时用shp。如果你只做回归Excel足够如果你要发带地图的论文shp不可替代。1.2 字段命名与单位口径要先对齐不同来源的夜间灯光产品字段命名五花八门常见的有sum_light、total_dn、mean_light、avg_dn、lit_area等。这份数据在Excel里一般会给出总量、均值、以及灯光覆盖面积这几类核心列。你需要特别确认两件事DN值的量纲和面积的单位。DN值Digital Number是灯光影像的原始灰度值不同传感器版本取值范围不同早期产品常见0-63后续产品扩展到0-255甚至更大。如果总量列是DN值直接求和那它的绝对数值没有物理意义只能做相对比较如果做过辐射定标单位可能是nW/(cm²·sr)那才具备跨年可比性。面积列要看清是平方公里还是公顷这直接影响你算灯光密度的结果。提示在正式分析前先抽一个省比如选一个你熟悉的省份把Excel里的总量、均值、面积三列做一次内部一致性检查——总量理论上约等于均值乘以有效像元数如果对不上说明口径里有你没注意到的处理比如剔除了背景噪声务必先问清楚再往下走。1.3 时间跨度里的断点要提前标记1992到2022横跨三十一年这期间灯光影像的源传感器经历过多次更替不同年份之间的绝对亮度并不天然可比。数据提供方通常做过跨年校正但你仍然要自己确认校正方式。常见的做法是以某一年为基准做线性回归校正或者用不变目标区域做相对辐射归一化。实操上我会在Excel里单独加一列数据版本标记把明显存在传感器切换的年份段标出来。做时间序列分析时要么在模型里加年份虚拟变量吸收这种系统性偏移要么直接对灯光总量取对数后再做差分弱化绝对量纲的影响。这一步不做很容易在趋势图里看到莫名其妙的台阶误以为是经济突变其实是数据源换了。2. 把Excel面板喂进统计软件的正确姿势Excel看着简单但夜间灯光面板有几个特有的坑处理不好会让回归结果失真。这一节按数据清洗的实际顺序讲。2.1 省份名称与代码的统一是第一步省级面板最常见的麻烦是名称不统一有的年份写内蒙古有的写内蒙古自治区有的用广西有的用广西壮族自治区。直接按名称合并或者做分组会出现同一省份被拆成两个实体的情况。我的做法是建一张省份对照表包含三列原始名称、标准化名称、行政区划代码。所有年份的数据先过一遍这张表统一成标准名称和代码再往下做。行政区划代码建议用六位国标码前两位就是省级标识后续如果要和地级市数据对接也方便。import pandas as pd # 假设原始Excel里省份列叫 province_raw df pd.read_excel(nightlight_province.xlsx) mapping pd.read_excel(province_mapping.xlsx) # 含 province_raw, province_std, code df df.merge(mapping, onprovince_raw, howleft) # 检查是否有未匹配上的 unmatched df[df[province_std].isna()][province_raw].unique() print(未匹配省份, unmatched)这段代码的关键在最后那行检查。我见过太多人merge完直接往下跑结果某几个省因为名称差异被静默丢弃样本量少了一截还不知道。每次合并后必须检查未匹配项这是铁律。2.2 缺失值与异常值的识别逻辑三十一年的面板缺失几乎不可避免。缺失分两种一种是某省某年整行没有另一种是某些指标列为空。前者可能是数据源本身没覆盖后者可能是提取失败。处理方式不同整行缺失要判断是真缺失还是该年该省不存在比如行政区划调整指标缺失则要考虑插值是否合理。异常值方面夜间灯光总量对面积敏感面积大的省份总量天然高所以直接看总量容易把大省当成异常。更稳妥的是看灯光均值和灯光密度总量除以行政区面积。如果某省某年的均值突然跳变超过合理幅度先别急着删回去查是不是该年影像有云覆盖或者传感器问题。检查项判断方法处理建议整行缺失按省份-年份做完整性矩阵区分真缺失与区划调整前者标记后者补正均值突变计算年度环比变化率超过阈值先核查影像质量再决定是否平滑总量与面积背离总量排名与面积排名对比面积大省总量高属正常重点看密度重复记录按省份-年份去重计数保留校正版本删除原始版本2.3 面板平衡性与软件读入做固定效应模型要求面板尽量平衡。三十一年理论上每省应有31条记录实际可能因为区划调整少几条。不平衡本身不是问题但你要清楚缺在哪。我通常会在读入后先跑一个平衡性检查# 检查每个省份的年份覆盖 coverage df.groupby(province_std)[year].agg([min, max, count]) coverage[expected] coverage[max] - coverage[min] 1 coverage[missing] coverage[expected] - coverage[count] print(coverage[coverage[missing] 0])读入Stata或R时注意年份列要转成数值型而不是字符串否则排序和差分都会出错。Excel里年份如果带年字导入后是字符务必先清洗。另外灯光总量这类右偏严重的变量建模前取自然对数几乎是标配能显著改善残差分布。3. Shapefile的空间分析从投影到提取shp格式才是这份数据真正拉开差距的地方。但空间数据的坑比表格多得多投影、坐标系、边界匹配每一步出错都会让结果面目全非。3.1 投影坐标系的选择直接影响面积计算夜间灯光shp通常自带地理坐标系经纬度单位是度。如果你要算灯光覆盖面积或者做密度分析必须投影到等面积投影否则高纬度地区的面积会被严重低估。国内省级分析常用Albers等积投影参数里中央经线和标准纬线要按研究区设定。在QGIS里操作图层右键 → 导出 → 另存要素为CRS选择自定义Albers标准纬线一般取25°和47°中央经线取105°。投影完再算面积结果才可信。我早期偷懒直接用经纬度算面积北方省份的灯光密度被系统性高估后来返工重算教训很深。3.2 灯光值提取到行政区划的完整流程很多时候你手上有一套自定义的空间单元比如城市群、流域、经济区需要把灯光值汇总进去。标准流程是分区统计Zonal Statistics。在QGIS里用栅格图层分区统计工具输入灯光栅格和分区矢量统计类型选Sum和Mean输出就是每个分区的灯光总量和均值。如果灯光数据是矢量点而非栅格则用按位置连接或者空间连接后分组求和。这里有个细节矢量点落在边界上时默认归属规则可能不符合你的预期建议先做一次边界缓冲检查确认没有大量点悬空在区划外。注意分区统计前务必确认栅格和矢量使用同一投影。坐标系不一致时QGIS虽然会自动提示重投影但自动转换有时会引入偏移手动统一投影更稳妥。3.3 空间自相关与热点分析的基本操作灯光数据的空间集聚特征很明显做全局Morans I是最常见的起点。在GeoDa里导入shp选好灯光均值变量构建空间权重矩阵常用Queen邻接或K近邻跑出来的Morans I如果显著为正说明相邻省份灯光水平相似集聚格局成立。局部指标LISA能进一步识别高-高集聚和低-低集聚区。做LISA时要注意显著性检验的多重比较问题GeoDa默认给的是伪p值样本量大时容易过度显著建议结合聚类图一起看别只盯p值。热点分析Getis-Ord Gi*则更适合看连续表面的冷热点分布输出的是z得分栅格正值为热点、负值为冷点。4. 时间序列上的可比性处理与趋势解读三十一年的数据最诱人也最危险的就是看趋势。趋势里既有真实的经济变化也有数据源切换带来的伪变化必须先把后者剥离。4.1 跨年校正的验证方法前面提到传感器更替会带来断点。验证方法很直接找几个经济数据相对平稳、没有大起大落的省份把它们的灯光总量时间序列画出来。如果某年出现所有省份同步的跳变基本可以判定是数据源问题而非经济问题。另一种验证是用重叠年份做交叉比对。如果数据提供方同时给了原始版本和校正版本取重叠年份算两者的比值比值稳定说明校正可靠比值波动大则要谨慎。我一般会把校正前后的序列叠在一张图上肉眼扫一遍异常台阶一目了然。4.2 增长率与弹性系数的计算口径灯光总量做趋势分析时直接看绝对值容易被量纲干扰取对数后的差分即对数增长率更稳健。如果你要算灯光对GDP的弹性注意两边都要用可比口径GDP用不变价灯光用校正后序列回归时控制省份固定效应和年份固定效应弹性系数才有解释力。有个容易忽略的点灯光总量受行政区面积影响跨省比较弹性时用灯光密度总量/面积或者灯光均值做因变量更合理。总量适合看规模密度适合看强度两者回答的问题不一样别混用。4.3 典型趋势形态的解读边界灯光时间序列常见的形态有三类持续上升对应城镇化推进、阶段性平台对应经济增速换挡、偶发下探对应短期冲击。解读时要结合当地实际情况不能一概而论。比如某个资源型省份灯光在特定年份明显回落可能是产业结构调整也可能是影像质量问题必须交叉验证。我个人的经验是任何单年度的异常都不要单独下结论至少看前后三年的走势是否连贯。灯光数据是代理变量不是经济指标本身它的价值在于提供空间上连续、时间上可比的相对信息而不是精确度量。5. 几个我踩过、你也大概率会踩的坑这一节不讲流程只讲教训。都是实际操作中真实遇到过、且常规文档里不会写的问题。5.1 边界文件版本不一致导致的面积漂移省级行政区划在三十一年里有过调整如果你用的边界文件是某一年版本的去套所有年份的灯光数据早期年份的面积会对不上。解决办法是尽量用与数据年份匹配的边界或者统一用最新边界但在分析时注明口径。面积漂移会直接影响密度类指标做跨年比较时尤其要小心。5.2 大文件读取的内存与精度陷阱三十一年的省级shp如果按栅格存储文件体积可能不小。用Python的geopandas读取时注意指定合适的dtype避免默认float64把内存吃满。另外Excel读取大表时如果列很多pandas默认可能把某些数值列读成object务必用dtypes参数显式指定否则后续计算会报类型错误。dtypes {year: int16, province_std: category, total_light: float32, mean_light: float32} df pd.read_excel(nightlight_province.xlsx, dtypedtypes)5.3 单位换算与量纲混淆的高频错误最常见的错误是把DN值总量当成物理亮度直接和其他研究对比。不同产品的DN量纲不同跨产品比较前必须做归一化。另一个高频错误是面积单位平方公里和公顷差100倍密度算错一个量级结论全反。我的习惯是在数据字典里把每个字段的单位写死每次引用前核对一遍。5.4 空间连接时的一对多静默膨胀用空间连接把灯光点挂到行政区上时如果一个点落在多个区的缓冲重叠处可能被重复计入导致总量虚高。做连接后一定要检查记录数是否等于原始点数不等就说明有重复归属需要设定优先级规则比如按最近邻或按面积占比分配。6. 把这份数据用出价值的几个方向数据本身是死的怎么用出花来才是关键。结合我见过的和做过的几个方向比较实在。区域经济差异分析是最直接的用法用灯光均值或密度做省际收敛性检验比单纯用GDP更能反映实际经济活动强度。城镇化研究里灯光覆盖面积的扩张速度可以作为建成区扩展的代理配合人口数据能算城镇化弹性。能源与环境方向灯光强度和能源消费、碳排放有较好的相关性适合做面板回归的因变量或工具变量。灾害与冲击评估里灯光时间序列的异常下探能快速定位受影响区域作为快速评估的辅助手段。需要提醒的是灯光数据是代理变量不是万能的。它能反映亮不亮但反映不了亮得有没有效率。做因果推断时它更适合当结果变量或稳健性检验的替代指标而不是核心解释变量。把它放在合适的位置价值才能最大化。最后分享一个我常用的检查习惯每次拿到新一年的数据先和上一年的同省数据做一次散点图看整体是否落在45度线附近。偏离太远的省份单独拎出来核查往往能提前发现数据问题。这个动作花不了几分钟但能挡掉大部分低级错误。