2021华为杯数学建模B题“空气质量预报二次建模” 预处理思路+Python代码

2021年中国研究生数学建模竞赛B题——空气质量预报二次建模 大气污染系指由于人类活动或自然过程引起某些物质进入大气中,呈现足够的浓度,达到了足够的时间,并因此危害了人体的舒适、健康和福利或危害了生态环境[1]。污染防治实践表明,建立空气质量预报模型,提前获知可能发生的大气污染过程并采取相应控制措施,是减少大气污染对人体健康和环境等造成的危害,提高环境空气质量的有效方法之一。目前常用WRF-CMAQ模拟体系(以下简称WRF-CMAQ模型)对空气质量进行预报。 阅读详情

简介

前阵子和小伙伴做了2021年华为杯研赛的B题“空气质量预报二次建模”,发现数据预处理一块挺有意思的,涵盖了常规的缺失值(随机缺失、指标缺失/列缺失、条目缺失/行缺失)、异常值(偏离正态分布、非负数据为负),以及不常规的协同处理等,一直想着有机会整理一下。

【注】只想看协同处理部分,即“4. 监测点A、A1、A2、A3数据预处理”的可直接转到:[Python] 反距离权重插值案例及代码_禾木页的博客-优快云博客

目录

1. 赛题及数据

1.1 竞赛试题

1.2 数据集预览

2. 监测点A数据预处理

2.1 监测点A一次预报数据处理

2.1.1 缺失值处理

2.1.2 异常值处理

2.2 监测点A实测时数据处理

2.2.1 整行数据缺失:删失处理

2.2.2 缺失值填补法1:前后均值填充

2.2.3 缺失值填补法2:随机森林插值

2.2.4 异常值处理step1:3西格玛原则

2.2.5 异常值处理step2:非负数据变成0

2.3 监测点A实测日数据处理

2.3.1 缺失值填补:用时数据均值填补

2.3.2 异常值处理step1:用时数据均值替换

2.3.3 异常值处理step2:3西格玛原则

2.3.4 异常值处理step3:非负数据变成0

3. 监测点B、C数据预处理 

4. 监测点A1、A2、A3数据预处理 

4.1 监测点A1、A2、A3一次预报数据

 4.2 监测点A1、A2、A3实测时数据处理

4.2.1 缺失值处理step1:反距离权重插值(IDW)

4.2.2 缺失值处理step2:随机森林插补

 4.2.3 异常值处理:3西格玛+非负数据处理

4.3 监测点A1、A2、A3实测日数据处理


1. 赛题及数据

        赛题及数据大家可自行前往“中国研究生创新实践系列大赛管理平台”下载,或者直接在网上搜索。 

1.1 竞赛试题

        2021年B题题目为“空气质量预报二次建模”,简而言之,核心任务是让你用已有的基于WRF-CMAQ模型得到的一次预报数据(包含6个污染物浓度指标和15个气象指标),加上提供的实测数据(6个污染物浓度指标和5个气象指标),在一次预报模型之上,建立一套比它更优的模型,因此叫二次建模。
        更优的标准是,使用二次建模预测结果中“空气质量指数AQI”预报值的最大相对误差应尽量小,且“首要污染物”他预测准确度尽量高。

1.2 数据集预览

官方提供数据集如下。
附件1 监测点A空气质量预报基础数据
附件2 监测点B、C空气质量预报基础数据
附件3 监测点A1、A2、A3空气质量预报基础数据 

从附件名字可以推测数据集的内部结构应该基本一致,只是监测点不同而已。事实也是如此,因此下面主要概述监测点A的数据,其他同理。

        时间那里有点乱,其实不难理解,重点关注“结束时间”就好,大家的结束日期都是2021年7月13日。
        怎么理解呢?
        首先,题目对时间表达有一个设定,即7:00代表的时点段为7:00-8:00,23:00代表的时间段是23:00-24:00。在此基础上:
(1)sheet1是预报的数据,题目设定是可以往后预报三天(当天+后两天),因此它站在7月13号预测,可以预测到7月15号。
(2)sheet2是实测时数据,题目设定每天预报的时间是早上七点,也就是说在7月13号做预报时,七点及之前所有真实的数据是可以获取的,因此“实测时数据”截止到7月13号7:00。
◆按道理,“7:00”代表7-8点,那么早上七点预测,“7:00”的数据应该是不可以用的,只能用到6:00(代表6-7点),但是题目自己设定可用,就不给自己增加难度啦~
(3)sheet3是实测日数据,经初步的验证,除O3外(后面会讲),发现“实测日数据≈实测时数据的24h平均”,7月13日时间数据只到早上七点,那它当然没有当天的日数据啦,所以只到7月12号。


2. 监测点A数据预处理

数据预处理一般包括缺失值处理和异常值处理。 

缺失值处理十分灵活,通常还要考虑数据实际含义;而且缺失值填补结果的优劣对后续的分析也有较大影响,本文大篇幅也是在进行缺失值的处理。

异常值处理相对而言较为简单,一般分两类异常。一是数据形态的异常,可用3西格玛原则处理;二是逻辑异常,比如数据集出现“非负数值为负”的情况;其他情况需根据具体案例判断是否存在异常。

以下数据处理均在Spyder3.7中进行。

import os
import pandas as pd
import numpy as np
#设置工作目录
os.chdir('C:\\Users\...)  
os.getcwd()
#导入数据:监测点A的三个数据集
df1A=pd.read_excel("附件1 监测点A空气质量预报基础数据.xlsx","监测点A逐小时污染物浓度与气象一次预报数据")
df2A=pd.read_excel("附件1 监测点A空气质量预报基础数据.xlsx","监测点A逐小时污染物浓度与气象实测数据")
df3A=pd.read_excel("附件1 监测点A空气质量预报基础数据.xlsx","监测点A逐日污染物浓度实测数据")

2.1 监测点A一次预报数据处理

2.1.1 缺失值处理

如果不做实际案例,网上的数据预处理教程往往是通过某命令找到缺失的位置,然后通过一些方法(如均值、众数、随机森林等)填充缺失值。但在这里你会发现,如果直接找缺失值,结果会显示不存在缺失。

由于isnull,any()只识别nan类型的缺失,为防止缺失的类型是null,我们将null转化为nan再查找一次,结果还是显示不存在缺失。

##df1A数据预处理
#查找变量是否存在缺失值
df1A.isnull().any()   
#避免缺失的类型是null,将null转化为nan
df1A = df1A.replace('null',np.NaN) 
df1A.isnull().any()

Out[1]: 
模型运行日期                False
预测时间                  False
地点                    False
近地2米温度(℃)             False
地表温度(K)               False
比湿(kg/kg)             False
湿度(%)                 False
近地10米风速(m/s)          False
近地10米风向(°)            False
雨量(mm)                False
云量                    False
边界层高度(m)              False
大气压(Kpa)              False
感热通量(W/m²)            False
潜热通量(W/m²)            False
长波辐射(W/m²)            False
短波辐射(W/m²)            False
地面太阳能辐射(W/m²)         False
SO2小时平均浓度(μg/m³)      False
NO2小时平均浓度(μg/m³)      False
PM10小时平均浓度(μg/m³)     False
PM2.5小时平均浓度(μg/m³)    False
O3小时平均浓度(μg/m³)       False
CO小时平均浓度(mg/m³)       False
dtype: bool

这就代表数据没有缺失值吗?

答案显然是否定的。数据缺失,不一定是“挖空式”的缺失,比如这份数据,如果是“模拟运行日期”或者“预测时间”的整一条数据缺失,通过上述方法是查找不到的。解决方式:

1、查看每一个“模型运行日期”下,是否有某个小时的缺失。

题目设定:每次模拟可以预测当天+未来两天共3天(72小时)的数据。

对每一个“模型运行日期”进行计数,发现每个“模型运行日期”下均有72条数据,即预测的三天。说明只要进行了预测,就一定会一次性预测三天的,不存在中间某个小时的预测缺失,代码见下文。

2、查看“模型运行时间”是否存在缺失。

方法1:上一步的输出结果的Index就是每一个模型运行日期,可以通过[F.index]逐一查看每个日期。但在这道题中,时间跨度将近一年,这样子看太麻烦了。

方法2:统计每个月份出现的天数,少于正常天数的月份说明那个月有“模型运行日期”的缺失,直接去找那个月份的数据。这里通过绘制“年”和“月”的交叉表,得到月份的情况(详见Out[2]),再根据月份情况查看是哪一天存在缺失(详见Out[3]-Out[5])。

分析
2020年7月份仅9天是因为从2020年7月23号开始的,到7月31日刚好9天,不存在缺失。
2020年11月份存在缺失,经查,为:2020-11-11
2021年1月份存在缺失,经查,为:2021-1-25
2021年5月份存在缺失,经查,为:2021-5-21
2021年7月份截止到7月13日,刚好13天,不存在缺失。

验证:不放心的话,可以验证一下是否仅有3天缺失。
2020年7月23日-2021年7月13日,共365-9=356天
F中共353条日期数据(或交叉表cross_ym2总和正好为353天[cross_ym2.sum().sum()]),正好缺失3天,分析结果应该无误。

缺失值处理:
一般情况下,都需要对缺失值进行填充,除实际意义外,若数据集中含有缺失值,后面很多命令是会报错的。但在这里我们并不补充缺失值,原因如下:

一是缺失的是整条数据,对后面数据处理不存在影响,只是后续需要合并不同监测点的数据时,不能简单的横向拼接;

二是考虑实际意义,一个“模型运行日期”的缺失代表预测的连续72条时数据的缺失,3个日期就代表3*72=216条数据缺失,不好补,可能也补不好,所以还是不补了。

既然不补,了解缺失值有什么作用呢?
个人看来,了解数据概况是预处理的重要一步,不管作不作处理,都要做到“心中有数”。

##df1A数据预处理
#查看每一个“模型运行日期”下,是否有某个小时的缺失
F=df1A['模型运行日期'].value_counts()
#输出结果:每个日期下均有72条数据(略)
#分析:72条时数据即预测的三天。说明只要进行了模拟,就会一次性模型三天的,不存在中间某个小时的预测缺失

#通过交叉表查看是否有“模型运行日期”的缺失
df1A['年份'] = df1A['模型运行日期'].dt.year   #提取“模型运行日期”的年份
df1A['月份'] = df1A['模型运行日期'].dt.month  #提取“模拟运行日期”的月份
cross_ym = pd.crosstab(index=df1A['年份'],columns=df1A['月份'],values=df1A['月份'],aggfunc='count') 
#由于每个“模型运行日期”对应72条数据,所以还需要除以72
cross_ym2 = cross_ym/72

Out[2]: 
月份      1     2     3     4     5     6     7     8     9     10    11    12
年份                                                                          
2020   NaN   NaN   NaN   NaN   NaN   NaN   9.0  31.0  30.0  31.0  29.0  31.0
2021  30.0  28.0  31.0  30.0  30.0  30.0  13.0   NaN   NaN   NaN   NaN   NaN
#查看是2020-11、2021-1、2021-5中是哪一天缺失
lack1 = df1A[(df1A['年份']==2020) & (df1A['月份']==11)]   #提取2020年11月数据
lack1d = lack1['模型运行日期'].value_counts()             #统计“模拟运行日期”,主要是想要它的index
lack1d.index.sort_values()        #.sort_values() 主要为了为日期排个序,方便看
Out[3]: 
DatetimeIndex(['2020-11-01', '2020-11-02', '2020-11-03', '2020-11-04',
               '2020-11-05', '2020-11-06', '2020-11-07', '2020-11-08',
               '2020-11-09', '2020-11-10', '2020-11-12', '2020-11-13',
               '2020-11-14', '2020-11-15', '2020-11-16', '2020-11-17',
               '2020-11-18', '2020-11-19', '2020-11-20', '2020-11-21',
               '2020-11-22', '2020-11-23', '2020-11-24', '2020-11-25',
               '2020-11-26', '2020-11-27', '2020-11-28', '2020-11-29',
               '2020-11-30'],
              dtype='datetime64[ns]', freq=None)

lack2 = df1A[(df1A['年份']==2021) & (df1A['月份']==1)]   #提取2021年1月数据
lack2d = lack2['模型运行日期'].value_counts()
lack2d.index.sort_values()
Out[4]: 
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
               '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08',
               '2021-01-09', '2021-01-10', '2021-01-11', '2021-01-12',
               '2021-01-13', '2021-01-14', '2021-01-15', '2021-01-16',
               '2021-01-17', '2021-01-18', '2021-01-19', '2021-01-20',
               '2021-01-21', '2021-01-22', '2021-01-23', '2021-01-24',
               '2021-01-26', '2021-01-27', '2021-01-28', '2021-01-29',
               '2021-01-30', '2021-01-31'],
              dtype='datetime64[ns]', freq=None)

lack3 = df1A[(df1A['年份']==2021) & (df1A['月份']==5)]   #提取2021年5月数据
lack3d = lack3['模型运行日期'].value_counts()
lack3d.index.sort_values()
Out[5]: 
DatetimeIndex(['2021-
数学建模竞赛实战:基于残差学习的空气质量预报二次建模与优化 在数据科学和机器学习领域,特征工程与模型优化是提升预测性能的核心环节。特征工程通过构建滞后特征、移动统计量及领域知识驱动的衍生特征,将原始数据转化为模型可理解的信号,直接影响模型的学习上限。其原理在于通过引入时间依赖性、统计概括和物理化学先验知识,让模型更好地捕捉数据中的复杂模式。在环境预测等实际问题中,结合业务规则(如空气质量标准)进行数据清洗与诊断,是保证模型稳健性的技术关键。残差学习作为一种有效的模型改进框架,专注于学习并修正基线模型的系统性误差,其价值在于能更高效地利用已有模型信息,提升最终预测的准 阅读详情

相关推荐

R 利用回归分析与时间序列预测北京市PM2.5

摘要 现代社会科技进步,人们的生活质量逐步提高,但伴随着各类工业和科技的发展,环境问题凸显,最初人们粗放式的经济发展方式在一定程度上对环境造成不可逆转的破坏。在各种环境污染问题,空气污染问题又是如今人们关注的重中之重。北京是我国首都,同时也是我国空气污染较为严重的几个北方城市之一,因此关注北京市空气污染情况是我国观测空气污染情况的重要关注对象之一。在本文中,首先,我就北京市PM2.5及其他污染物和气象情况的近几年观测数据做出相应回归分析,建立回归模型试图利用已知的其他污染物和气象情况信息对PM2.5做出预

weixin_45529837的博客 1万+

2021华为杯研赛选题建议与思路

给大家的选题建议: A题 相关矩阵组的低复杂度计算和存储建模 这道题目需要充分挖掘矩阵间关联性,以实现低复杂度的计算和存储,需要有相当的数学功底,存在最优解,推荐数学等相关专业,或者对其有强烈兴趣的同学选择。 B题 空气质量预报二次建模 这道题目相对而言难度适中,典型的数据挖掘类题目,建议计算机等相关专业同学选择,其中可以用一些机器学习、深度学习算法进行建模。要注意可视化很重要。 C题 帕金森病的脑深部电刺激治疗建模研究 此题尤其建议计算机专业研究脑认知方向的同学选择,其他方向和专业不推荐此题,可能需要补的

qq_54783078的博客 2690

基于机器学习的PM2.5浓度预测模型

基于机器学习的PM2.5浓度预测模型 1. 背景介绍 1.1 PM2.5概述 PM2.5是指环境空气中直径小于或等于2.5微米的颗粒物,主要来源于燃煤、机动车尾气排放和工业生产等。PM2.5颗粒物由于体积小、质量轻,可长时间悬浮在空气中,易

AI天才研究院 2648

置顶必读(2) |《滚雪球学数学建模》专栏目录 & 历年国赛/美赛真题库 & 真题解析(持续更新中)

本专栏《滚雪球学数学建模》采用“从零开始、逐步滚雪球”的学习路径,把数学建模的基础理论、方法工具与大量实战真题(尤其是国赛题,涵盖2025-1992所有真题)有机融合,形成一套系统化训练路线。非常适合零基础入门、希望提升模型与工程化能力的本科/研究生,以及备战全国大学生数学建模竞赛(国赛/省赛)的同学。加油,我们一起把建模能力打造成可迁移的核心竞争力!

**My Coding Family** 26万+

华为杯数学建模题:关于空气质量预报的二次建模

建立空气质量预报模型对于减少大气污染对人体健康和环境的危害具有重要作用,如何建立准确的空气质量预报模型,提前获取可能发生的大气污染和采取相关措施具有重要意义。 本文针对WRF-CMAQ模拟体系预测模型进行改进研究,主要解决了在污染物排放不变的情况下,将不同特征的气候条件进行分类并得出不同特征气候条件对污染物浓度的影响程度的问题,针对A、B、C三个监测点建立合适的二次预报数学模型用以预测未来几天6种常规污染物单日浓度值,同时根据相邻区域的污染物浓度相关性,建立四个临近区域内的协同预报模型以提升对观测点污染物浓度预测的准确性。 针对问题一,我们根据《环境空气质量指数(AQI)技术规定(试行)》(HJ633-2012)来计算空气质量指数(AQI)用以判别空气质量等级。首先根据公式1.1计算得到各项污染物的空气质量分指数(IAQI),公式1.1如下: IAQI_P=(IAQI_Hi-IAQI_Lo)/(BP_Hi-BP_Lo )⋅(C_P-BP_Lo )+IAQI_Lo (1.1) 空气质量指数(AQI)取各分指数中的最大值,即 AQI=ma

2021年华为杯数模B题.zip

分享一下刚刚参加过的华为杯数模题目,供小伙伴后续练手。

UE5新手必看:如何用蓝图系统快速打造赛车游戏(含Chaos Physics配置)

本文为UE5新手提供使用蓝图系统快速打造赛车游戏的完整指南,涵盖Chaos Physics配置、载具蓝图架构设计、控制逻辑实现等关键步骤。通过详细的实战案例和优化技巧,帮助开发者高效构建具备专业物理反馈的赛车游戏原型。

weixin_29001327的博客 387

AD18 PCB模块的Copy

在PCB布局时,时常会将元器件先分模块进行排布,最后才会进行总体的布局,在局部布局的时候,想要移动一个模块的器件总是很麻烦,需要选中全部才能进行移动,有些时候还有选漏的情况,所以会将局部布局的模块把它看做一个整体进行移动,效果如下,元件,布线,铜皮,过孔以及元件编号的位置摆放都和源模块一模一样。4、再选中需要复用的模块内的元件,按照第3步的顺序排序,粘贴刚刚复制的Channel Offset参数。在PCB布局时,有多个模块原理图是一模一样的情况,我们可以只画一个模块,之后灵活应用模块,进行copy。

qq_53859658的博客 3239

从零到一:RT-Thread与W5500的硬件抽象层设计哲学与实践启示

本文深入探讨了RT-Thread操作系统下W5500以太网模块的硬件抽象层(HAL)设计哲学与实践。通过GD32F103和STM32F103平台的适配案例,详细阐述了如何利用RT-Thread的驱动框架实现跨平台硬件无关性、模块化设计及配置定制,为嵌入式开发者提供了可复用的HAL设计方法论和实战经验。

7z8x2c4v6b9的博客 197

别再死记硬背了!一张图搞懂无刷电机半桥与全桥驱动的核心差异(附避坑指南)

本文深入解析无刷直流电机的半桥与全桥驱动方式的核心差异,提供直观对比与选型指南。半桥驱动结构简单、成本低,适合低要求场景;全桥驱动性能优越但复杂,适用于高精度控制。文章还包含实战避坑指南,帮助工程师优化驱动方案选择与应用。

weixin_29290947的博客 319

IMU数据处理避坑指南:从理论到实践的加速度计重力消除方案

本文详细解析了IMU数据处理中的重力消除技术,从理论基础到实践应用,涵盖了加速度计和陀螺仪的核心问题。通过ROS2实战案例,介绍了静态标定与动态校准的技术对比,以及多传感器融合的进阶策略,帮助开发者避免常见陷阱,提升IMU数据处理的精度和效率。

purple的博客 741

从数据库到数据仓库:数据仓库导论

本文为数据仓库导论,旨在介绍数据仓库的基本理念和应用场景,帮助读者理解数据仓库的重要性及其在企业中的实际应用。

探索大数据世界 - 深入解析数据存储、分布式计算与人工智能 2784

MFC实现图书管理系统(附完整源码)

MFC实现图书管理系统(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 800

基于YOLOv11的军事目标识别系统设计与实现(坦克、舰船检测)

DOTA-v2.0(包含多种军事装备的航拍图像)图片数量:11,268类别:18类,包括坦克、舰船、战斗机等分辨率:800×800~4000×4000HRSC2016(高分辨率舰船检测数据集)图片数量:1,061类别:舰船及子类特点:包含多种视角和复杂背景图片数量:5,000+类别:22种军用飞机标注:精确边界框自建数据集建议收集来源:公开军事演习视频、卫星图像、模拟游戏截图数据增强:模拟不同天气、遮挡、低光照等战场环境。

YOLO 450

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: [Python] 反距离权重插值案例及代码
下一篇: [Python] 散点图(二维散点图、三维散点图、散点图矩阵)
禾木页
博客等级 码龄8年 38粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

禾木页

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值