news 2026/10/10 3:42:40

2003-2023地级市工业三废面板数据整理与清洗指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2003-2023地级市工业三废面板数据整理与清洗指南

做了几年环境数据分析,手里的城市面板数据少说也整理过几十套。要说哪类数据最让人又爱又恨,工业三废绝对排得上号——想研究污染排放和经济增长的关系,它是核心变量;想评估环境规制的影响,它是因变量;可真正拿过来用的时候,统计范围变来变去、指标名称前后不一致、个别城市某些年份整个空白,每一件事都能让人折腾掉半条命。最近我把2003到2023年全国地级市层面的工业三废数据重新梳理了一遍,从零散来源、指标核对到面板结构整合,过程持续了半个多月。这篇主要讲清楚这套数据里到底有什么、整理时哪些环节最要命、哪些坑是新手必踩,以及最终形成的数据集长什么样,希望对正在做环境经济、产业升级、区域可持续发展研究的朋友有参考价值。

1. 数据集的全貌与设计思路

1.1 那“三废”到底指哪些指标

工业三废通常指工业废水、工业废气、工业固体废物,地级市层面能拿到的指标一般按统计口径拆成三大块:

  • 工业废水:废水排放量、化学需氧量(COD)排放量、氨氮排放量,以及废水治理设施数、处理能力。
  • 工业废气:二氧化硫(SO2)排放量、氮氧化物(NOx)排放量、烟尘排放量、工业粉尘排放量,部分年份和城市还会把烟尘与粉尘合并为“烟粉尘”,另有废气治理设施数等辅助指标。
  • 工业固废:一般工业固体废物产生量、综合利用量、处置量、贮存量,加上危险废物产生量、利用处置量等,个别年份还单列了倾倒丢弃量。

整理数据时最头疼的就是指标口径的变化。以废气为例,早期统计系统把“烟尘”和“工业粉尘”分开填报,后来统一为“烟粉尘”;废水COD指标在2010年前后经历过实测法和产排污系数法切换;固废的“综合利用量”很多时候包含了往年综合利用往年贮存量,不同城市统计习惯并不完全一致。所以我的处理原则是保留原始指标名,不在原始层做合并,只在最终分析表里给出映射指标,这样别人拿到数据还能反查原始来源。

1.2 时间跨度为什么选2003到2023

2003年是一个比较清晰的起点。2003年之前,地级市层面的环境统计数据相当残缺,很多城市缺年份、缺指标,推到上世纪90年代,数据质量根本不足以支撑可靠的面板分析。2003年以后,地级市行政区划总体进入相对稳定阶段,虽然中间仍然有撤地设市、合并拆分等变化,但大部分变动都能找到可追溯的官方记录,跨年拼接才有可能实现。

2023年作为终点,是因为环境统计年报的发布普遍存在一到两年的滞后期,2023已经是目前能拿到的最完整的年份。二十年的时间窗口还有一个额外的好处:跨度足以覆盖多个五年规划期,政策周期完整。滞后一期、差分、对数变化率这些常规处理都具备足够的样本支撑,不至于因为年份太短导致自由度过低。

1.3 数据层级与统计口径的最小共识

地级市层级在统计上包含地级市、地区、自治州和盟,副省级城市也在其中。因为部分省直管县级市不在标准地级市代码表里,我没有直接采用行政区划代码作为唯一主键,而是给每个城市分配了稳定的内部ID,同时保留年份和行政区划代码两列作为辅助索引。这样即使区划调整,面板也能通过内部ID保持连续。

统计口径层面要特别注意“工业源”的边界。这几年环境统计调查范围经历过调整,重点调查单位覆盖范围变了,部分规模较小的工业企业不再全口径纳入统计,直接导致某些城市废水排放量出现台阶式下降。这不是录入错误,而是统计范围变了。遇到这种情况,我在数据集里额外加了一个“口径说明”字段,把每个指标出现统计方法变更的年份标出来,避免下游分析的时候对着突变点发呆。

2. 清洗与对齐:最容易翻车的三个环节

2.1 不同来源同一指标对不上怎么办

地级市三废数据通常有三个来源:省级环境统计资料汇编、地级市年度环境状况公报、历年统计年鉴。同一个城市同一年同一个指标,三个来源有时能差出一倍。这背后不是谁抄错了,而是统计范围、核算方法和发布时间不同导致的口径差异。

我常用的处理原则是:优先采用省级环境统计汇编的口径,因为它在编制时会对下辖城市做二次校核,数值内部一致性最好;公报数据往往更偏向于对外宣传口径,数据好看但不太适合跨城市横向比较;统计年鉴的数据出版滞后半年到一年,适合补充缺项但不宜作为主数据源。

如果两个来源数值差异在5%以内,我会保留主数据源,并在备注列记录另一个来源。差异超过5%就要逐市排查,排查重点通常是“是否包含生活源”“是否包含乡镇工业”“是否采用了新版核算系数”。我遇到过某地级市因为小造纸厂、小食品加工厂这类规模以下企业是否纳入统计范围,直接导致废水排放量翻倍的情况,这不是计算问题,是统计对象问题,只能靠人工核对原始报表说明来定夺。

2.2 行政区划调整的连环影响

二十年间地级市层面出现过几类区划调整:撤地设市、地级市扩张吞并周边县、县改区,还有少数地级市被撤销合并。区划调整对不同指标的影响并不一样,不能简单地“一刀切”处理。

我维护了一张行政区划变更映射表,格式大致如下:

年份城市内部ID变更类型影响范围说明
2005年C101撤地设市原地区下辖县整体转入新设市,需重新匹配全部指标
2011年C215市辖区扩张周边两县划入市区,部分指标应重新核实
2018年C332地级市撤销原市辖县并入相邻两市,原ID保留至变更前为止

做面板分析时,我会把涉及区划调整的城市统一标记为“受区划调整影响”,并在回归模型里控制一个变更虚拟变量。否则固定效应模型很容易把区划调整引起的数值变化误读成污染排放的真实变化,结论直接偏掉。

2.3 缺失值的补还是不补

缺失大致分三类。第一类是客观未发布,也就是当年该城市没有上报或年报没有公开,这种直接留空不填。第二类是统计口径导致数值为“0”,比如取消了某类行业统计后填报为零,需要区分“真零”和“未统计”,按指标本身特性打上不同标识。第三类是出版漏印,个别年份单个指标异常为零,但前后年份都正常,这种可以结合省级数据和相邻城市趋势做插补。

我的处理办法是:单独生成一套“缺失标识变量”,把所有缺失的来源都记录下来,而不是直接用均值填充。工业三废排放量和城市产业结构高度相关,均值填充会把钢铁型城市和旅游型城市的所有差异全部抹掉,看起来补全了,实际上一跑回归全是假信号。宁可让模型损失几个观测值,也不能用烂数据糊弄过去。

3. 实操:从原始数据到可直接回归的面板

3.1 为什么用长表结构而不是宽表

最终数据集采用“一年一市长表”的结构,一行是一个城市-年份的唯一组合,字段包括:城市ID、年份、省份、城市名称、废水排放量、COD、氨氮、SO2、NOx、烟粉尘、固废产生量、综合利用量、处置量,以及若干缺失标识和口径说明列。

选长表而不是宽表,核心原因有两个:一是绝大多数统计分析软件的面板回归命令都要求长表格式,需要整理成年份在前、城市在后的“个体-时间”结构;二是长表便于做数据追加,以后补入2024年数据,直接往后面加行就行,不用改表结构。如果下游需要宽表做矩阵运算,可以随时通过透视表转换,长表本身是更好的存储中间格式。

3.2 用Python完成加载、索引构建与清洗

这里给出一段核心实现,我实际清洗时的主要逻辑都集中在这一段。

import pandas as pd import numpy as np # 读取原始数据 raw = pd.read_csv('city_triple_waste_raw.csv', encoding='utf-8') # 年份清洗 raw['year'] = pd.to_numeric(raw['year'], errors='coerce') raw = raw.dropna(subset=['year']) # 匹配城市ID对照表 id_map = pd.read_csv('city_id_map.csv') raw = raw.merge(id_map, on=['province', 'city_name'], how='left') assert raw['city_id'].notna().all(), "存在无法匹配的城市" # 单位统一:早期数据有的是吨、有的是万吨、有的是亿吨 raw['waste_water'] = np.where( raw['water_unit'] == '亿吨', raw['waste_water'] * 10000, # 万吨 raw['waste_water'] ) raw['so2'] = np.where( raw['so2_unit'] == 'kg', raw['so2'] / 1000, # 吨 raw['so2'] ) # 缺失标识:单独生成一列,保留缺失信息 for col in ['cod', 'ammonia_nitrogen', 'so2', 'nox', 'smoke_dust', 'solid_waste', 'waste_utilized']: raw[col + '_missing'] = raw[col].isna().astype(int) # 面板排序并重置索引 panel = raw.sort_values(['city_id', 'year']).reset_index(drop=True) print('面板规模: {} 行, {} 个城市'.format( panel.shape[0], panel['city_id'].nunique()))

这段代码的核心不是功能复杂,而是把“数据可追溯”放在第一位。单位换算和缺失标识都额外生成单独列或单独数据文件,不直接覆盖原始值,这样下次分析时任何人需要反查原始单位,都能通过对照表还原。不要小看这个习惯,我在半路接收别人整理好的数据时,最痛苦的就是遇到单位已经换算、但又不说明原来是什么单位的文件。

3.3 排放强度指标的计算

绝对排放量在不同城市之间不好直接比较,所以我预计算了几个派生指标:

  • 工业废水排放强度:废水排放量 / 规模以上工业总产值,单位是吨每万元。
  • 单位工业增加值SO2排放量:SO2排放量 / 工业增加值,单位是吨每亿元。
  • 固废综合利用率:综合利用量 /(产生量 + 综合利用往年贮存量)× 100%。

计算时有两个细节。第一个是工业总产值的统计口径,规模以上工业企业的统计起点在2007年有过调整,从年主营业务收入五百万元提高到两千万元,前后年份的分母口径不一样,直接算强度会有一个断点,所以我在指标说明里标注了分母口径版本。第二个是固废综合利用率公式,部分城市把往年贮存量纳入分母,部分城市不纳入,两者差值可能达到十几个百分点,单独做了一列“利用率口径”标记,避免横向比较时出错。

3.4 数据质检四步走

数据质检我至少过四步。第一步查重复值,按城市ID加年份检查重复行,防止不同来源数据重复拼接没有发现。第二步查极端值,某个指标偏离中位数达到数倍时,逐条调出原始填报记录人工核对。第三步做突变点检测,对每个城市计算相邻两年环比变化率,指标翻倍或者减半的年份全部标记出来,再确认是口径调整还是真实变化。第四步查面板平衡性,统计每个城市的年份连续性,连续缺失超过三年的城市单独列清单,并且不纳入部分需要连续观测的分析。

做完这套检查后,我对几十个城市的记录做了修正,比如把某两年误用的“类比推算值”单独标记为“推算数据”,并给出了可靠性分级推荐。可靠性分级本身也是一个字段,0到3级分别对应官方发布、年鉴转录、推算插补、无法核实。我建议所有做面板研究的人拿到数据后先看一眼可靠性分级分布,再决定要不要用那些补出来的数。

4. 常见问题与排查技巧实录

4.1 某市某年几乎所有指标全空

这种情况最常见的诱因是行政区划调整,或者该市当年统计工作移交给其他机构,填报关系发生了转移,导致数据断档。某些被整体并入相邻城市的地级市,在合并年份后所有指标都会停止更新,这不是数据缺失,而是统计主体已经不存在了。

处理方法很简单:不要尝试补值,保持缺失,并在备注列标注“区划调整导致断档”。如果分析的时间窗口刚好跨越合并年份,可以考虑两种方案,一是只保留合并后新市的连续面板,二是把原城市和承接城市分别做成两条记录,再用变更映射表关联起来,而不是人为拼一个“连续性”数据出来。

4.2 同一年同一个指标两个来源差出20%以上

先检查是不是统计范围不一致。最常见的错误是把“全市”数据当作“市辖区”数据,或者反过来。有些城市公报里公布的是城区数据,省级汇编里却是全辖区的数据,两者相差20%是非常正常的。

处理逻辑是:保留主数据源,在备注记录第二来源,并生成一个“数据来源冲突”标识列,方便下游分析者在建模时决定剔除还是保留。特别提醒,不要因为差值不大就随意合并两个来源的数值,更不要直接求平均,因为两个来源的误差来源不同,求平均并不能得到更接近真值的数。

4.3 相邻年份数值突然翻倍又回落

这类情况多半来自核算方法切换。2008年到2011年之间,很多污染物指标从实测法转向产排污系数法核算,同一座产业结构的城市在相邻年份会突然出现台阶式变化。这时加入年份固定效应是比强行调整历史数据更可信的处理方式。

如果非要跨断点比较,可以用断点两侧同时存在的新旧口径指标做一个比例换算,但换算结果只能当参考值,不适合直接作为精确数值进入回归。我一般建议把新旧口径用两个变量同时放进模型,利用断点作为自然实验的边界来处理。

4.4 零值陷阱

工业三废数据里最危险的零值是“假零”。一个拥有大型化工园区的城市,危险废物产生量指标为0,基本可以断定是未统计,而不是实际为零。处理这种问题的经验是:用同一产业结构、相近人口和工业产值的邻近城市做横向对比,如果相邻城市该指标正常而目标城市为0,就应该标记为“疑似漏报”,而不是当作真实零值进入计算。

我在数据集里专门给这类疑似漏报增加了一个“低质零值”标识,方便分析时控制。直接删掉还是保留,取决于具体研究设计,但不该让它们无声无息地混进面板。

4.5 行政区划变动时城市代码也变了怎么办

统计部门的行政区划代码会随区划调整更新,代码变了不代表城市换了。我自己维护的ID对照表里保留了两种代码结构:一种是国标行政区划代码代码,另一种是自己生成的连续城市ID。分析时优先使用连续城市ID,行政区划代码只作为辅助索引。

合并后的承接城市,其指标数值天然包含了被并入区域的数据,这是真实情况。在研究产业转移或者环境规制时,需要明确标注合并前后口径是否平滑,必要时以合并事件作为分析窗口的断点来处理。

5. 这套数据可以做什么分析

5.1 环境库兹涅茨曲线验证

城市层面人均GDP与工业SO2排放量的关系,是这套数据最典型的应用场景。用人均GDP对数和平方项作为核心解释变量,城市和年份双固定效应,2003到2023的跨度恰好覆盖了从工业化加速期到平台期的全过程。做这类分析时建议把废水和固废指标也跑一遍,因为不同污染物的曲线形态可能完全不同,有的呈倒U型,有的还在上升期,结论会比只看单一污染物丰富得多。

需要注意工业增加值数据本身也是分年调整口径的,固定效应模型里加入年份虚拟变量能吸收掉一部分口径变化,但分省、分行业的增加值统一修正还是需要单独做一遍。

5.2 污染转移与产业梯度分析

高污染行业从中心城市向周边城市转移,是一个被反复讨论的现象。用这套数据可以这样操作:把地级市按经济发展水平分组,观察高排放行业迁入地的固废产生量和废气排放量是否同步上升,再结合城市间的距离或交通通达度构造空间权重矩阵。固废产生量在这里是个很好的佐证指标,因为它在统计上比气体排放更稳定,不会因为气象条件或监测点位调整而变化。

5.3 政策事件对比分析

某些省份在不同年份实施过专项排放削减行动,或者划定过重点治理区。借助地级市面板可以做前后对比:以该省地级市为处理组,相邻省份城市为对照组,控制城市固定效应和年份固定效应,观察行动前后处理组与对照组的排放量差异。这个设计的核心假设是“对照组本来也应该有相同趋势”,所以做之前要检验处理组和对照组在行动前的三废排放趋势是否平行。

5.4 区域绿色转型的量化评估

把三废指标和工业增加值结合,构造各市单位工业产值的污染排放指数,用指数变化率衡量转型速度。这个指数可以拆成废水强度、废气强度、固废强度三个子项,也可以加权为一个综合指数。唯一需要强调的是,指数一定得把构造公式写清楚,不同研究者用不同权重算出来的“绿色转型指数”之间没有可比性。我交付的版本里同时保留了未加权和按污染物毒性加权两个版本的指数。

个人实操体会

整理这套数据到最后,最大的体会是:工业三废数据不怕有缺失、不怕有异常,怕的是你不知道哪一年哪个城市的数据为什么变了。把每一次口径切换、每一次区划调整、每一次异常修复都记录在备注和标识列里,数据集的长期价值才会真正体现出来。

后续我打算在现有面板上继续补两个方向,一是各市重点治理行动的时间点,二是把个别指标做行业层面的拆分。如果大家在用这套数据时遇到口径存疑或者数值异常的情况,欢迎一起交流排查思路。毕竟这种长面板数据,前期整理工作做得越扎实,后面跑模型的时候才敢对结论有信心。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 3:42:40

微电网调度中的风光场景生成与削减:蒙特卡洛+概率距离法实战

做微电网调度优化的时候,我大部分时间其实不是在写约束,而是在想办法对付不确定性。前段时间接了一个模拟项目,给定一片风电和一片光伏作为可调度的分布式电源,目标是最小化运行成本。第一步很常规:用蒙特卡洛法把未来24小时的风光出力抽成5000个随机场景。第二步就出问题了——…

作者头像 李华
网站建设 2026/10/10 3:41:45

Spring Boot在线考试系统:并发写入与事务边界实战

简介:这份资源是面向高校计算机相关专业学生与Java开发初学者的毕业设计参考文档,围绕基于Spring Boot框架的在线考试系统展开,帮助读者理解如何用主流技术栈完成一个具备实际业务价值的Web项目。文档完整覆盖需求分析、系统架构、数据库设计…

作者头像 李华
网站建设 2026/10/10 3:40:41

代码签名技术全解析:原理、证书选型与CI/CD实践

1. 代码签名到底在签什么:从一次线上事故说起前阵子帮一个做桌面工具的朋友排查问题,用户反馈安装包双击之后系统直接弹窗拦截,提示"未知发布者",甚至有的机器连运行权限都不给。代码本身没毛病,功能测试全过…

作者头像 李华
网站建设 2026/10/10 3:40:14

从“无标题”到正式命名:一句话锁定项目内核

项目清单里躺着个“无标题”,听起来像个段子,但我这几年真见过不少项目,起点就是这个状态。新建文档默认叫“未命名”,新建仓库默认叫“my-project”,而有些项目,连“未命名”都没人愿意给它起,…

作者头像 李华
网站建设 2026/10/10 3:39:59

PCA9422与MK64FN1M0VDC12协同实现高可靠电源管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华