1. 课程导入与环境监测数据认知

欢迎进入《Python环境监测数据处理入门项目》。在动手写第一行代码之前,我们需要先弄清楚一件事:我们将来要处理的“数据”究竟长什么样。环境监测数据并不是抽象的数字集合,它来自空气自动站、水质采样点、噪声监测仪等真实设备,每一种数据都有自己的指标含义、采集频率和存储格式。只有先建立对数据对象的清晰认知,后续的读取、清洗、统计和可视化才有明确的目标。

一、环境监测数据的三大来源

环境监测按介质通常分为空气质量、水质和噪声三类,它们的数据特征差异明显。

空气质量数据主要来自城市环境空气自动监测站,常见指标包括 PM2.5、PM10、二氧化硫(SO₂)、二氧化氮(NO₂)、一氧化碳(CO)和臭氧(O₃),以及空气质量指数 AQI。自动站一般每小时上传一次数据,因此一天一个站点会产生 24 条记录。AQI 并不是直接测量的,而是由各项污染物浓度按《环境空气质量指数技术规定》分段计算得出,取值 0~500,并对应优、良、轻度污染等等级。理解这一点很重要:AQI 是派生指标,而 PM2.5 等浓度是原始指标。

水质数据多来自地表水断面或排污口,常见指标有 pH、溶解氧(DO)、高锰酸盐指数、氨氮、总磷、总氮等。水质监测的采样频率远低于空气自动站,可能是每日、每周或每月一次,因此数据行数少但字段含义更复杂,还常伴随采样时间、断面名称、水温等辅助信息。pH 无量纲,溶解氧单位是 mg/L,这些单位差异在后续计算中必须留意。

噪声数据通常以等效连续 A 声级 Leq 表示,单位为分贝 dB(A),功能区不同则昼间、夜间限值不同。噪声监测可能是连续的小时均值,也可能是某次测量的瞬时值,数据字段相对简单,但时间粒度不统一是常见问题。

环境监测数据:来源 → 格式 → 处理 空气质量 PM2.5 / PM10 / SO₂ / NO₂ CO / O₃ / AQI 小时值 · 站点多 · 行数大 水质 pH / 溶解氧 / 氨氮 高锰酸盐指数 / 总磷 / 总氮 采样频次低 · 单位不统一 噪声 等效声级 Leq 昼间 / 夜间限值 dB(A) · 时间粒度不一 常见存储格式 CSV:纯文本、逗号分隔 Excel:多工作表、含格式 JSON:键值嵌套、接口常用 Python 处理主线 读取 pandas.read_* 清洗 缺失值 / 类型 / 异常 统计 均值 / 超标率 / 分组 可视化 matplotlib 图表

二、三种常见数据格式的差异

环境监测数据落地到文件时,最常见的是 CSV、Excel 和 JSON 三种格式,它们在 Python 中的读取方式不同,踩坑点也不同。

CSV 是纯文本,用逗号或制表符分隔字段,体积小、通用性强,自动站导出的原始数据多为 CSV。它的风险在于编码(常见 UTF-8 与 GBK 混杂)和表头不规范,例如首行是“站点名称:XX站”这样的说明文字而非字段名,直接读取会把说明行当成数据。此时需要用 skiprows 跳过,或指定 header 行号。

Excel 文件(.xlsx)可以包含多个工作表,单元格还带格式和合并单元格,人工整理的月报、季报常用这种格式。读取时用 pd.read_excel(path, sheet_name=...),要特别注意合并单元格会导致列名出现 Unnamed: 1 之类的占位符,需要重命名。

JSON 以键值对和嵌套结构组织数据,环境监测平台的 API 接口返回的往往是 JSON,例如一个站点对象里嵌套着多条小时记录。读取后需要先“展开”嵌套层,才能转成规整的二维表。

import pandas as pd

# CSV:跳过前两行说明,指定编码
df_csv = pd.read_csv("air_station.csv", skiprows=2, encoding="gbk")

# Excel:读取指定工作表
df_xlsx = pd.read_excel("water_report.xlsx", sheet_name="2024年3月")

# JSON:读取后展开嵌套的记录列表
import json
with open("noise_api.json", encoding="utf-8") as f:
    raw = json.load(f)
df_json = pd.json_normalize(raw["records"])

上面这段示例代码展示了三种格式的最小读取路径,实际项目中还要根据列名、时间字段和单位做进一步处理。请注意,示例中的文件名和参数属于教学假设,真实数据需按实际文件调整。

三、监测指标的含义与判读意识

处理数据之前,必须知道每个字段“代表什么、单位是什么、什么算超标”。以 PM2.5 为例,我国《环境空气质量标准》二级标准日均限值为 75 μg/m³,年均限值为 35 μg/m³;水质中氨氮的地表水Ⅲ类限值为 1.0 mg/L;噪声 1 类功能区昼间限值为 55 dB(A)。这些限值不是让我们死记,而是提醒我们:统计时不能只算平均值,还要算超标天数、超标率,才能回答“这段监测期内环境质量是否达标”这个真正的问题。

此外,指标之间还存在派生关系。AQI 由六项污染物分指数取最大值得到,水质综合污染指数由多项指标加权计算。理解派生逻辑,才能判断某个字段是原始测量值还是计算值,避免重复计算或误用。

四、项目整体介绍与学习路径

本课程围绕一个贯穿始终的小项目展开:读取某城市一个月的空气自动站数据,完成清洗、统计与可视化,输出一份月度空气质量简报。项目虽小,但覆盖了环境监测数据处理的核心环节。

学习路径按“认知—工具—处理—分析—交付”推进:先认识数据类型与格式(本章),再搭建 Python 与 pandas 环境,掌握 DataFrame 的基本操作;随后进入真实数据的读取与清洗,处理缺失值、异常值和类型转换;接着学习按时间分组统计、计算日均值与超标率;最后用 matplotlib 绘制浓度变化曲线和 AQI 等级分布图,形成可交付的分析结果。每一章都会围绕项目中的具体数据展开,而不是孤立地讲语法。

建议在开始后续章节前,先准备一份自己的示例数据文件(哪怕只有几十行),跟着课程边学边练。环境监测数据处理的能力,来自对真实数据“脏、乱、杂”的反复处理,而不是背诵函数参数。

本章不需要写复杂代码,但请记住三个关键词:介质(空气、水、噪声)、格式(CSV、Excel、JSON)、指标(浓度、单位、限值、派生关系)。它们将决定你后面每一次 read_csv、每一次 groupby 到底在做什么。