新闻详情

新闻详情

首页 / 资讯中心 / 详情

Pandas缺失值处理全攻略:从定位到填充的完整数据清洗流程

发布时间:2026/9/18 7:30:48来源:尧图网络
Pandas缺失值处理全攻略:从定位到填充的完整数据清洗流程
简介这是一份面向Python数据分析初学者的Pandas数据预处理学习笔记PDF聚焦4.11节缺失值处理。内容从缺失值的产生讲起先说明Pandas用NaN表示缺失值再系统讲解dropna、fillna、isnull、notnull四个核心函数的用法与参数细节包括axis控制删除行或列、how选择删除全空或含空行、thresh设置非空数量阈值、subset指定检查列范围。随后通过具体DataFrame实例演示如何删除缺失行/列、用固定值0或前向/后向填充、使用interpolate线性插值并配有运行结果方便对照练习笔记还补充了创建缺失值数据、制造异常数据并填充、模拟电商商品销售数据集进行综合练习等实操环节能帮助读者快速上手数据清洗流程。整个文件为单个PDF文档大小约375KB内容紧凑适合已经掌握Pandas基础、想强化数据清洗技能的读者随时翻阅目前已有1348人浏览学习。1. 数据清洗第一步为什么说缺失值比离群值更容易毁掉模型拿到一份四个仓库的库存表同一件商品在一个仓库有记录在另一个仓库完全没有先用groupby一聚合结果里全是空值平均库存直接被算成 0。这是数据预处理里最典型的场景数据里的问题往往不是某个离群的 9999而是一个个悄悄出现的NaN。Pandas 用NaN标记缺失值并围绕它提供isnull、dropna、fillna、interpolate四类接口搭配好就是一套完整的数据清洗流程。下面把这条流程拆开讲从缺失值定位开始到按参数删除、按策略填充最后落到“把异常值转成 NaN 再统一处理”这个能直接复用的技巧。适合刚入门数据分析、遇到报错就dropna()的新手也适合想搞懂thresh、subset这些冷门参数到底怎么用的从业者。2. 缺失值体检isnull、notnull 与 info() 组合定位 NaN2.1 NaN 的来历与类型转换开始之前先构造一份带缺失值的 DataFrame作为全文的演示数据。这里用典型的员工信息表包含姓名、年龄、工资、性别四列。import numpy as np import pandas as pd print(pd.__version__) # 先看版本不同版本 API 行为有差异 df pd.DataFrame( [ [张三, np.nan, 3000, M], [李四, 28, np.nan, np.nan], [王五, 25, np.nan, W], [赵六, 20, 4000, M], [np.nan, np.nan, np.nan, np.nan], ], columns[姓名, 年龄, 工资, 性别], )np.nan是浮点标准里的 Not a Number它的一个特性是np.nan np.nan返回False所以千万不要用df[df[年龄] np.nan]去筛缺失值写了也拿不到结果。所有判断要交给isnull()或notnull()。Pandas 在读 CSV、Excel 时会把空白单元格自动解析成NaN同时把整列推断为float64。这造成一个隐蔽现象明明源文件里是整数年龄导入后 dtype 却变成 float。如果发现原本应该是 int 的列变成 float大概率就是列里混入了 NaN这是数据预处理中最常见的类型陷阱。2.2 用 info() 快速掌握数据规模df.info()不是专门的缺失值函数但对清洗流程第一步来说性价比最高因为它直接输出每列的非空值数量df.info()运行结果会显示每列的 Non-Null Count姓名4 个非空年龄3 个工资3 个性别3 个最后一行还有索引范围和内存占用。这意味着四列各缺失一处第五行是全空行。相比打印整个 DataFrame 用肉眼找洞info()更适合刚接手一份陌生数据时做快速体检它帮你确认哪些列还能救哪些列已经漏成筛子。2.3 isnull() 与 sum() 计算缺失分布df.isnull()返回一个形状和原表完全一致的布尔 DataFrame每个元素用True标记缺失位置。只看布尔表还不够直观叠加sum()才能得到统计口径df.isnull() # 布尔矩阵True 代表缺失 df.isnull().sum() # 每列缺失个数 df.isnull().sum().sum() # 全表缺失总数三个调用逐层递进。df.isnull()定位具体格子比如第一行第二列是True表示张三的年龄缺失。sum()对列方向求和布尔值True当作 1 计算得到每列缺失数量。第二个sum()再对 Series 求和就是整张表的 NaN 总数。真实项目里我很少逐行看布尔矩阵而是直接看df.isnull().sum()配合df.isnull().mean()得到缺失率超过 70% 的列基本就考虑放弃或重构了。2.4 notnull() 与布尔索引筛选健康样本df.notnull() df[df[年龄].notnull()]notnull()是isnull()的严格互补True表示非缺失。第二行的写法是数据清洗里常用的布尔索引df[条件]中的条件是一串布尔值Pandas 保留条件为True的行。这里只以“年龄”为过滤标准年龄非空的行全部保留哪怕工资或性别仍然是 NaN。这个行为比dropna()更可控它按字段逐个过滤而不是一竿子打死一整行。例如分析“有年龄的用户中谁缺工资”时先用df[年龄].notnull()圈定人群再对结果做二次缺失检查比直接删行更符合业务逻辑。四种检测方法的适用场景对比如下方法返回内容典型用途df.info()文本摘要快速查看每列非空数量与类型df.isnull()布尔 DataFrame精确到元素级别的缺失定位df.isnull().sum()Series按列统计缺失数量df.notnull()布尔 DataFrame配合布尔索引过滤非缺失样本百万行级数据里isnull()会生成等大的布尔矩阵内存压力是原表的好几倍。遇到超大文件时建议先抽样或分块读取用df.sample(100000)统计缺失分布再决定整表处理策略避免一次性把全量布尔结果展开。3. dropna 删除策略axis、how、thresh、subset 的取舍逻辑3.1 删除行还是删除列先说 axisdropna的完整函数签名是DataFrame.dropna(axis0, howany, threshNone, subsetNone, inplaceFalse)。第一个要决策的就是axis删行还是删列。axis0或axisindex删除含有缺失值的行axis1或axiscolumns删除含有缺失值的列。df.dropna() # 默认 axis0删除任何含 NaN 的行 df.dropna(axis1) # 删除任何含 NaN 的列默认调用df.dropna()后只剩“赵六”这一行因为只有他全字段完整。df.dropna(axis1)则更极端四列里只有姓名没有任何 NaN其余三列全被删光表就剩一列了。这个示范说明一个边界列不多、但每列都有少量缺失时axis1会造成灾难性的信息损失。删列的真正适用场景是“某一列缺失率过高比如 80% 以上的字段值是 NaN该列已经失去分析价值”此时删列是止损而非浪费。3.2 howany 与 howall缺失容忍度how参数决定删除的触发条件。howany是默认值只要行或列里出现任意一个 NaN 就删除howall则要求整行或整列全部为 NaN 才删除。df.dropna(howall) # 删除全为 NaN 的行 df.dropna(howany) # 默认行为有 NaN 就删前面构造的数据里恰好有一行全 NaNdf.dropna(howall)会精准删掉这一行其他四行保留因为它们至少有一个有效字段。实际业务中howall最有用的场景是清理 CSV 文件末尾的空行或 Excel 中误插入的空行既能清掉垃圾数据又不会误伤正常记录。howany则适合字段都必填的严格表比如订单表中订单号、金额、时间任何一项缺失整条订单都不能参与统计。3.3 thresh不是缺失个数是有效值个数thresh是 dropna 参数里最容易被误读的一个。它的语义是“保留至少有 n 个非缺失值的行或列”。单位是非缺失值的数量不是缺失值的数量。df.dropna(thresh3)逐行数有效值张三和非缺失值有 3 个年龄缺失李四只有 2 个工资和性别都缺失王五有 3 个赵六 4 个最后一行 0 个。thresh3的结果是保留下张三、王五、赵六三行。这个参数解决的问题是“我不在乎缺哪一个字段但整条记录至少要有几个关键字段”。比如用户画像表有 10 个维度业务要求每条样本至少覆盖 6 个维度才有建模价值直接用thresh6一条参数搞定不用写复杂的多列条件组合。提示如果需求是“最多容忍 2 个缺失值”应该写成thresh总列数-2而不是thresh2。把thresh理解为“及格线”而不是“扣分项”能少踩一半坑。3.4 subset只在业务关键列里查缺失subset接收一个列名列表指定 dropna 时只在这些列内评估缺失条件。它解决的是“有些字段缺失无所谓但核心字段不能缺”这类业务诉求。df.dropna(subset[工资, 性别])这个调用只检查工资和性别两列两列都非空的行才能保留。逐行看李四性别缺失被删王五工资缺失被删全空行直接不满足条件剩下的只有张三和赵六。注意它评估的是 subset 范围内的列姓名即便缺失也不会触发删除。用户注册表就是一个典型场景user_id和reg_time是必填字段avatar_url是选填字段那么dropna(subset[user_id, reg_time])就合理。如果对全表任意缺失都执行删除注册数据会损失惨重。3.5 删除后的索引断裂与重置删除行之后索引不会自动重排。如果删掉了中间几行索引会变成 0、2、4 这样的跳跃状态。后续做groupby或merge时断裂的索引容易引发“看似对齐、实则错位”的隐性 bug。df_clean df.dropna(subset[工资]).reset_index(dropTrue).reset_index()将索引恢复为从 0 开始的连续整数序列dropTrue表示丢弃原索引而不是把它作为一列插进数据里。项目实践中我习惯在所有dropna之后立即接一个reset_index(dropTrue)减少后续代码中的不确定性。3.6 dropna 参数速查表参数取值含义axis0/index、1/columns按行还是按列删除howany、all有 NaN 就删还是全 NaN 才删thresh整数 n行/列至少保留 n 个非缺失值subset列名列表只在指定列内评估缺失inplaceTrue/False是否原地修改原 DataFrameinplace默认False返回新对象原表不动。很多教程推荐df.dropna(inplaceTrue)但项目里我建议统一写成df df.dropna(...)。原因很简单原地修改会打断链式操作调试时想对比删除前后的差异也麻烦而没有inplace的写法天然保留原数据的一个备份。4. fillna 填充方案常量填充、ffill / bfill 与 interpolate 线性插值4.1 常数填充与按字段差异化填充删除缺失值会损失样本填充则能把样本保留下来。最直接的填充方式是常数填充df.fillna(0)这个操作把整张表的 NaN 都替换成 0。视觉上干净了但必须警惕一个坑0 本身可能是一个合法的业务值。工资列为 0 和工资缺失是完全不同的概念前者代表“没有工资”或“无偿劳动”后者代表“没录进来”。如果是库存表0 还意味着“缺货”直接fillna(0)可能会让业务误判。更精细的做法是按列填充不同列用不同策略df[年龄] df[年龄].fillna(df[年龄].median())先计算年龄列的中位数再把它填进缺失位置。选择中位数而非均值是因为中位数对离群值更稳健。年龄列如果混入一个 200 的异常值均值会被拉高中位数依然稳定。注意这里必须写成df[年龄] ...的形式把填充结果重新赋回原列只写df[年龄].fillna(median)不会修改原数据。4.2 ffill 与 bfill顺序数据的继承式填充基于顺序的填充方式是缺失值处理的另一条路线。前向填充用上一个有效值补缺口后向填充用下一个有效值补缺口df.fillna(methodffill) # 前向填充method 写法在老版本中常见 df.fillna(methodbfill) # 后向填充新版 pandas 中更推荐直接使用专用方法df.ffill() df.bfill()ffill的执行逻辑是沿着axis0即从上到下逐行继承李四缺失的工资被张三的 3000 填充缺失的性别被上一行的M填充。bfill则相反从下往上取下一个有效值。但填充绝不等于“找到值就行”。ffill和bfill都强依赖行顺序什么时候适合用时间序列。比如传感器每 5 秒上报一次温度某次网络抖动断了一个点用上一秒的温度近似是合理的工程假设。如果数据本身无序比如多个仓库的库存表用ffill就是把 A 仓库的库存继承给 B 仓库没有任何业务依据。顺便说一句ffill有一个边界限制第一行之前的空缺没有值可继承最后一行的空缺也无法被bfill处理。实际项目里可以组合使用但组合后那些“推测值”和“真值”在后续分析里最好能被区分出来。4.3 interpolate 线性插值的计算逻辑interpolate(methodlinear)是比 ffill 更平滑的填充方式。它不直接继承某个值而是在前后两个有效值之间按线性关系推算中间值。df.interpolate(methodlinear)以工资列为例第一行是 3000第四行是 4000第二、三行的工资缺失就会按照索引位置的线性比例折算分别得到约 3333 和 3666。相比ffill直接把两行都填成 3000插值保留了数据的趋势变化。interpolate适合数值型连续字段比如房价走势、气温变化、销量序列。但它有两个前提数据本身有顺序逻辑且相邻值之间存在近似的线性关系。在类别型字段上它无能为力性别列缺失时会原样保留因为字符串无法做数值插值。4.4 填充方式选择对照把三种填充方法在同一份数据上跑一遍print(df.fillna(0)) print(df.ffill()) print(df.bfill()) print(df.interpolate(methodlinear))四次输出结果各不相同而且从代码层面看都“没错”。关键不是哪个函数更高级而是填充结果是否贴近业务事实。数据分析中缺失值处理没有标准答案只有相对更合理的假设。填充方式填充来源数据前提主要风险fillna(0)外部常量缺失有明确的业务含义0 被当作有效值参与统计fillna(median)列统计量数值型分布偏态降低方差弱化波动信息ffill()/bfill()相邻行数据严格有序顺序乱则结果无意义interpolate()前后值拟合连续数值线性变化非线性场景失真5. 异常值转 NaN 再统一处理一个能直接抄进项目的填充技巧5.1 用布尔掩码把异常值变成 NaN缺失值处理和异常值处理经常是同一件事。一个常见做法是先把不合理的取值转成 NaN让异常值“归入”缺失体系再统一走前面的删除或填充流程。df1 pd.DataFrame(np.random.randint(0, 10, (4, 5))) df1[df1 5] np.nan # 把小于 5 的取值视为异常转为缺失 print(df1) df1.fillna(-1, inplaceTrue) print(df1)核心是df1[df1 5] np.nan这一行。df1 5生成布尔掩码Pandas 把掩码为True的格子全部赋值为NaN向量化执行不需要写循环。之后fillna(-1)把所有异常位替换成-1这里的-1不是正常数值而是“这里曾出现过异常”的标记。用不可能出现的值保留异常痕迹比直接删掉更有审计价值。5.2 仓库库存表的完整预处理流程用配套素材里的库存数据走一遍完整流程。原始数据是一个字典列表四个仓库的商品种类不完全一致缺失值表示该仓库没有这种商品的库存记录。items2 [ {内存条: 33, 移动硬盘: 35, 鼠标: 15, 主板: 8, 键盘: 45}, {内存条: 10, 键盘: 50, U盘: 15, 鼠标: 5, 主板: 17, 显示器: 5}, {内存条: 24, 键盘: 14, U盘: 18, 鼠标: 19, 主板: 12, 移动硬盘: 14, 显示器: 16}, {U盘: 20, 内存条: 30, 鼠标: 35, 移动硬盘: 4, 键盘: 10}, ] store_items pd.DataFrame(items2, index[仓库 1, 仓库 2, 仓库 3, 仓库 4])先判断缺失情况print(store_items.isnull().sum())结果显示移动硬盘、显示器等列在部分仓库缺失。这个缺失的业务含义是“库存为 0”而不是“数据丢失”。此时用dropna()删除任意含 NaN 的行四个仓库会被全部删光因为没有一个仓库覆盖所有商品用ffill()会让仓库 1 的移动硬盘库存继承仓库 3 的值纯属虚构。正确的做法是用 0 填充表示该仓库确实没有此商品store_items.fillna(0, inplaceTrue) print(store_items)填充完成后做一次验证确保全表没有遗漏的 NaN并检查每个仓库的库存总量是否合理assert store_items.isnull().sum().sum() 0 print(store_items.sum(axis1))assert语句会在条件不满足时抛出异常相当于给数据清洗加了一道保险。sum(axis1)按行求和得到每个仓库的商品总数如果某个仓库求和后明显偏低说明填充掩盖了更深层的源数据问题需要回到采集端排查。整个处理顺序检测缺失 → 判断缺失的业务含义 → 选择删除或填充 → 用统计量校验是最常复用的数据清洗套路。遇到同类项目时把“所有小于阈值的值转 NaN”这类规则抽象成一个小函数传入阈值和填充值后续换数据源只需要改动两处参数。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

智能家居实战指南:从协议选型到自动化调试的避坑之路 2026/9/18 8:16:13

智能家居实战指南:从协议选型到自动化调试的避坑之路

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

阅读更多 →
轻量级gods-eye-view系统:事件流+语义图谱+动态SVG实战 2026/9/18 8:16:13

轻量级gods-eye-view系统:事件流+语义图谱+动态SVG实战

1. 什么是“gods-eye-view”?它不是玄学,而是可落地的系统性观察方法“gods-eye-view”这个词最近在技术复盘、产品设计、城市治理、甚至教育评估场景里高频出现,但它绝不是什么新造的营销话术或抽象概念。我带团队做过7个跨部门协同项目&…

阅读更多 →
从CNN到Transformer:深度学习模型架构演进与应用对比 2026/9/18 8:16:13

从CNN到Transformer:深度学习模型架构演进与应用对比

1. 神经网络模型演进全景图在深度学习领域,模型架构的迭代演进犹如一场永不停歇的技术马拉松。作为从业十余年的算法工程师,我见证了从传统神经网络到现代大语言模型的完整技术跃迁。这场变革不仅仅是参数量的量变,更是模型架构设计哲学的根本…

阅读更多 →
AST与调用链分析在智能回归测试筛选中的应用 2026/9/18 8:16:13

AST与调用链分析在智能回归测试筛选中的应用

1. 项目背景与核心价值在持续集成和敏捷开发成为主流的今天,每次代码提交后的回归测试执行时间已经成为制约研发效率的瓶颈。某互联网企业的实测数据显示,其核心业务系统每次代码提交平均需要执行3872个回归测试用例,耗时达到47分钟。而经过分…

阅读更多 →
SpringBoot智慧图书管理系统设计与实践 2026/9/18 8:16:13

SpringBoot智慧图书管理系统设计与实践

1. 项目背景与核心价值在数字化阅读和无人零售双重趋势推动下,传统书店运营模式正面临转型升级的关键节点。去年参与某连锁书店智能化改造项目时,亲眼见证了管理员手工登记借阅记录导致的3.7%账实不符率。这正是我们开发智慧图书管理系统的现实意义——通…

阅读更多 →
OP_OPTION 宏详解:CANN opbase 中算子精度模式的封装与 OpImplMode 使用指南 2026/9/18 8:13:13

OP_OPTION 宏详解:CANN opbase 中算子精度模式的封装与 OpImplMode 使用指南

OP_OPTION 宏详解:CANN opbase 中算子精度模式的封装与 OpImplMode 使用指南 【免费下载链接】opbase 本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。 项目地址: https://gitcode.com/cann/opbase 导读 OP_OPTION 是 C…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞