当前位置: 首页 > news >正文

【数学建模学习笔记】缺失值处理

Pandas 缺失值处理:零基础小白入门指南

在数据分析中,“缺失值”(比如表格里的空白格、显示 “NaN” 的位置)是很常见的问题 —— 可能是数据录入时漏填了、设备故障没采集到,或者用户没回答某个问题。如果不管这些缺失值,会导致分析结果不准、模型跑不起来。下面用最通俗的语言,带你理解 8 种常用的缺失值处理方法,以及怎么用 Python 的 Pandas 实现。

一、先搞懂基础:我们要处理什么样的数据?

首先,我们需要导入工具和数据(就像打开 Excel 文件一样):

# 导入必备工具(numpy和pandas是数据分析的“瑞士军刀”)
import numpy as np
import pandas as pd# 读取在线Excel数据(里面有100行、10列数据,列名是x1到x10)
df = pd.read_excel('https://labfile.oss.aliyuncs.com/courses/40611/%E7%BC%BA%E5%A4%B1%E5%80%BC%E5%A4%84%E7%90%86.xlsx')# 查看前5行数据(能看到有些位置是“NaN”,这就是缺失值)
print(df.head())
# 查看数据大小(100行,10列)
print(df.shape)

运行后会看到类似这样的表格,其中 “NaN” 就是我们要处理的缺失值:

x1x2x3x4x5x6x7x8x9x10
085.2885.7487.8870.1997.1384.0989.6790.7188.0768.15
174.3074.4171.50NaN74.9581.7061.2774.7372.1988.11
285.2286.2383.8887.4873.4273.1988.5386.9883.2590.07

二、8 种缺失值处理方法:通俗解释 + 代码实现

每种方法都像 “补衣服的不同针法”,适用于不同情况,我们一个个说清楚。

1. 剔除标记 / 剔除缺失值(最简单但 “浪费” 数据)

通俗理解:

直接把有缺失值的 “整行” 删掉 —— 比如表格里第 1 行的 x4 是 NaN,就把第 1 行整个去掉,只保留所有列都没缺失值的行。
(注:原文中 “剔除标记” 和 “剔除缺失值” 代码完全一样,本质都是删除含缺失值的行,这里合并解释)

代码实现:
# 定义一个“删除缺失值行”的函数
def drop_missing(df):# df.dropna():删除所有包含NaN的行return df.dropna()# 应用函数,得到处理后的数据
df_drop = drop_missing(df)# 查看处理后的数据(会发现行数变少了,比如从100行变成80行)
print(df_drop.head())
# 查看处理后的数据大小(对比原数据,行数减少)
print(df_drop.shape)
适用场景:
  • 原数据行数很多(比如 10000 行),缺失值的行很少(比如只有 50 行);
  • 缺失值的行对分析影响不大,删了也不影响结果。
缺点:

如果数据本身不多(比如只有 100 行),删完可能只剩 50 行,会丢失很多信息。

2. 均值填充(用 “平均分” 补空白)

通俗理解:

比如要补 x4 列的缺失值,就先算 x4 列所有非缺失值的 “平均分”(均值),然后把所有 NaN 都换成这个平均分。
例:x4 列非缺失值的平均分是 79.8,那第 1 行 x4 的 NaN 就换成 79.8。

代码实现
# 定义“均值填充”函数
def mean_fill(df):# df.mean():计算每列的均值;df.fillna(...):用均值替换NaNreturn df.fillna(df.mean())# 应用函数
df_mean_fill = mean_fill(df)# 查看处理后的数据(x4列的NaN变成了均值,比如79.8)
print(df_mean_fill.head())
适用场景:
  • 数据是 “连续型” 的(比如成绩、身高、体重,不是 “男 / 女”“及格 / 不及格” 这种分类);
  • 数据分布比较均匀,没有特别大或特别小的极端值(比如全班成绩在 60-90 分之间,没有 0 分或 100 分)。
缺点:

如果数据有极端值(比如全班大多 60-90 分,但有 1 个 0 分),均值会被拉低,填充后会不准。

3. 中心化填充(用 “中间值” 补空白,比均值更稳)

通俗理解:

“中心化” 其实是 “中位数” 的通俗说法 —— 把某列非缺失值按从小到大排序,取中间的那个数(如果个数是偶数,就取中间两个数的平均),然后用这个中间值补 NaN。
例:x4 列非缺失值排序后是 [70,78,80,87,90],中间值是 80,那 NaN 就换成 80。

代码实现:
# 定义“中位数填充”函数(原文“中心化填充”即中位数填充)
def median_fill(df):# df.median():计算每列的中位数;用中位数替换NaNreturn df.fillna(df.median())# 应用函数
df_median_fill = median_fill(df)# 查看处理后的数据(x4列的NaN变成了中位数,比如80.88)
print(df_median_fill.head())
适用场景:
  • 和均值填充一样,适用于连续型数据;
  • 数据有极端值时(比如有 0 分或 100 分),中位数比均值更稳定,填充更准。
例子:

全班成绩:60,70,80,90,100 → 均值 80,中位数 80(一样);
全班成绩:0,70,80,90,100 → 均值 68(被 0 分拉低),中位数 80(不受极端值影响),此时用中位数填充更准。

4. 众数填充(用 “最常见的值” 补空白)

通俗理解:

“众数” 是某列中出现次数最多的数 —— 比如 x3 列中 “77.26” 出现了 5 次,是出现最多的,那 x3 列的 NaN 就都换成 77.26。

代码实现:
# 定义“众数填充”函数
def mode_fill(df):# df.mode():计算每列的众数(可能有多个,取第一个,即.iloc[0])return df.fillna(df.mode().iloc[0])# 应用函数
df_mode_fill = mode_fill(df)# 查看处理后的数据(x3列的NaN变成了众数,比如77.26)
print(df_mode_fill.head())
适用场景:
  • 数据是 “分类型” 的(比如性别:男 / 女,颜色:红 / 蓝 / 绿,成绩等级:及格 / 不及格);
  • 连续型数据中某值出现次数特别多(比如全班成绩大多是 80 分)。
例子:

如果要补 “性别” 列的缺失值,假设 “男” 出现了 60 次,“女” 出现了 40 次,众数是 “男”,就把缺失值都填 “男”。

5. 三倍 / 六倍标准差填充(用 “偏极端但合理的值” 补空白)

通俗理解:

先搞懂两个概念:

  • 标准差:反映数据的 “离散程度”—— 标准差越小,数据越集中(比如全班成绩都在 75-85 分,标准差小);越大越分散。
  • 三倍标准差:均值 + 3× 标准差(比如均值 79.8,标准差 7.7,三倍标准差就是 79.8+3×7.7=102.9)。

这种方法是用 “均值 + N× 标准差”(N=3 或 6)来补缺失值,填充的是一个 “比大多数值大,但还在合理范围内” 的数。

代码实现:
# 定义“标准差填充”函数,默认3倍,可改6倍
def std_fill(df, times=3):# 计算每列的均值和标准差mean = df.mean()std_dev = df.std()# 填充值 = 均值 + times×标准差fill_value = mean + times * std_dev# 用计算出的填充值替换NaNreturn df.fillna(fill_value)# 应用3倍标准差填充
df_3std_fill = std_fill(df, times=3)
# 应用6倍标准差填充(把times改成6即可)
df_6std_fill = std_fill(df, times=6)# 查看结果(3倍填充值比6倍小,比如x4列3倍是102.9,6倍是125.9)
print(df_3std_fill.head())
print(df_6std_fill.head())
适用场景:
  • 数据符合 “正态分布”(比如成绩、身高,大多数值集中在中间,少数在两端);
  • 希望缺失值填充一个 “偏上限但仍在统计合理范围内” 的值(比如工业数据中,缺失值可能是 “接近上限的正常值”)。
缺点:

如果数据不符合正态分布(比如大多是低值,少数是高值),填充值会偏离实际,不太准。

6. 插值填充(用 “前后值的趋势” 补空白,适合按顺序的数据)

通俗理解:

像 “填表格的中间数”—— 比如 x3 列第 0 行是 87.88,第 2 行是 83.88,第 1 行是 NaN,就按 “线性趋势” 算:(87.88+83.88)/2=85.88,把第 1 行 x3 的 NaN 换成 85.88。
这种方法会考虑数据的 “顺序关系”,不是只看整列的统计值。

代码实现:
# 定义“插值填充”函数,默认线性插值(按直线趋势补)
def interpolate_fill(df, method='linear'):# df.interpolate():插值填充,method='linear'是线性插值return df.interpolate(method=method)# 应用线性插值填充
df_interpolate = interpolate_fill(df)# 查看结果(比如x3列第1行的NaN变成了85.88)
print(df_interpolate.head())
适用场景:
  • 数据有 “时间顺序”(比如每月销售额、每天气温,行是按时间排的);
  • 数据有明显的 “趋势”(比如销售额逐月增长,气温逐年上升)。
例子:

如果要补 “2023 年 3 月销售额” 的缺失值,已知 2 月是 10 万,4 月是 14 万,线性插值就是 12 万,符合 “每月增 2 万” 的趋势。

7. 模型填充(用 “AI 预测” 补空白,最复杂但最准)

通俗理解:

把 “补缺失值” 变成一个 “预测问题”—— 比如要补 x4 列的缺失值,就用其他列(x1,x2,x3,x5...)作为 “特征”,用 x4 列非缺失值的数据训练一个简单的模型(比如线性回归、随机森林),然后用模型预测 x4 列的缺失值。

为什么原文没实现?

原文说 “数据量太小(100 行),不适宜模型填充”—— 因为模型需要足够多的数据才能训练准确,数据少的话,预测结果会很不准。

适用场景:
  • 数据量很大(比如 10000 行以上);
  • 各列之间有明显的 “关联关系”(比如 x4 和 x1、x2 相关性强,能通过 x1、x2 预测 x4);
  • 对缺失值填充的准确性要求很高(比如科研、重要业务分析)。
缺点:
  • 操作复杂(需要懂机器学习基础);
  • 计算量大,耗时久。

三、总结:怎么选对处理方法?

用一张表帮你快速对应场景和方法:

处理方法核心逻辑适用场景优点缺点
剔除缺失值删有缺失的行数据多、缺失少简单快丢数据
均值填充用平均分补连续型数据、无极端值简单、符合整体水平受极端值影响大
中位数填充用中间值补连续型数据、有极端值稳、不受极端值影响没利用数据分布信息
众数填充用最常见值补分类型数据、某值出现次数多适合分类数据连续型数据用着不准
三倍 / 六倍标准差用偏上限的合理值补正态分布数据、需合理极端值符合统计规律非正态分布不准
插值填充按前后趋势补时间序列数据、有明显趋势考虑顺序关系无趋势数据用着不准
模型填充用 AI 预测补数据多、列间有关联、要求高准确性最准复杂、耗资源

四、小白实操建议

  1. 先看数据情况:用df.isnull().sum()查看每列有多少缺失值(比如 x4 列有 10 个 NaN,x3 列有 8 个);
  2. 优先选简单方法:如果数据多、缺失少,先试 “剔除缺失值”;如果是连续型数据,先试 “均值 / 中位数填充”;如果是分类数据,先试 “众数填充”;
  3. 验证结果:处理后用df.head()df.describe()查看数据是否合理(比如填充值有没有明显异常,比如 x4 列都是 70-90 分,填充后突然出现 200 分,就是错了)。
http://www.xdnf.cn/news/1421191.html

相关文章:

  • 数学分析原理答案——第七章 习题13
  • 文件夹上传 (UploadFolder)
  • crypto-babyrsa(2025YC行业赛)
  • 【系统架构师设计(8)】需求分析之 SysML系统建模语言:从软件工程到系统工程的跨越
  • 【机器学习学习笔记】numpy基础2
  • 基于 HTML、CSS 和 JavaScript 的智能图像边缘检测系统
  • ESB 走向黄昏,为什么未来属于 iPaaS?
  • 【第十一章】Python 队列全方位解析:从基础到实战
  • 计算机网络技术(四)完结
  • 9月1日
  • 8Lane V-by-One HS LVDS FMC Card
  • 【STM32】贪吃蛇 [阶段 8] 嵌入式游戏引擎通用框架设计
  • IO进程线程;标准io;文件IO;0901
  • OPENCV 基于旋转矩阵 旋转Point2f
  • Python核心技术开发指南(030)——函数入门
  • PAT乙级_1093 字符串A+B_Python_AC解法_含疑难点
  • 基于 C 语言的网络单词查询系统设计与实现(客户端 + 服务器端)
  • Python OpenCV图像处理与深度学习:Python OpenCV特征检测入门
  • AI时代SEO关键词实战解析
  • Python3环境搭建教程 - 使用Conda工具
  • CGroup 资源控制组 + Docker 网络模式
  • 【并发场景问题】超卖、一人一单业务问题的解决方案
  • 大型语言模型监督微调(SFT)
  • openharmony之sandbox沙箱机制详解
  • K8S网络组件Calico深度解析
  • Python OpenCV图像处理与深度学习:Python OpenCV图像几何变换入门
  • 深入解析 Go 程序逆向风险与防护策略
  • 如何对嵌入式软件进行单元测试
  • 无重复字符的最长子串,leetCode热题100,C++实现
  • Vue3响应式陷阱:如何避免ref解构导致的响应式丢失