Pandas-数据清洗与处理

Pandas-数据清洗与处理

    • 一、数据清洗的核心目标
    • 二、缺失值处理
      • 1. 缺失值检测
      • 2. 缺失值处理策略
        • (1)删除法
        • (2)填充法
    • 三、异常值识别与处理
      • 1. 异常值检测方法
        • (1)统计法
        • (2)业务规则法
      • 2. 异常值处理策略
    • 四、重复数据处理
      • 1. 重复数据检测
      • 2. 重复数据处理
    • 五、数据格式转换与标准化
      • 1. 日期时间格式转换
      • 2. 文本数据清洗
      • 3. 数据类型转换
    • 六、应用实例:完整数据清洗流程

数据清洗与处理往往占据最多的时间,现实世界中的数据很少是完美的——它们可能包含缺失值、异常值、重复记录,或是格式混乱、命名不规范的字段。Pandas作为Python数据处理的瑞士军刀,提供了强大而灵活的工具来应对这些问题。

一、数据清洗的核心目标

数据清洗的最终目的是提升数据质量,为后续分析和建模奠定基础。具体来说,需要实现以下目标:

  • 完整性:处理缺失值,确保关键信息不缺失
  • 一致性:统一数据格式、命名规范和取值标准
  • 准确性:识别并修正异常值、错误数据
  • 唯一性:去除重复记录,避免分析结果偏差
  • 可用性:将数据转换为便于分析的结构(如日期类型、分类编码)

围绕这些目标,Pandas提供了从简单到复杂的一系列处理函数,掌握它们的组合使用是高效清洗数据的关键。

二、缺失值处理

缺失值是数据清洗中最常见的问题,Pandas通过isnull()dropna()fillna()等函数形成完整的处理链条。

1. 缺失值检测

首先需要定位缺失值的位置和比例:

import pandas as pd
import numpy as np# 读取示例数据
df = pd.read_csv('messy_data.csv')# 检测每列缺失值数量及比例
missing_count = df.isnull().sum()
missing_ratio = (missing_count / len(df)).round(3)
missing_df = pd.DataFrame({'缺失值数量': missing_count,'缺失比例': missing_ratio
})
print("缺失值统计:")
print(missing_df[missing_df['缺失值数量'] > 0])  # 只显示有缺失的列

2. 缺失值处理策略

根据缺失比例和字段重要性,选择不同的处理方式:

(1)删除法

适用于缺失比例极高(如超过80%)或对分析无影响的字段,或缺失行数量极少的情况:

# 删除缺失比例超过50%的列
threshold = len(df) * 0.5
df = df.dropna(thresh=threshold, axis=1)# 删除关键字段(如用户ID)缺失的行
df = df.dropna(subset=['user_id', 'order_date'])
(2)填充法

对于重要字段,需根据字段类型选择合理的填充值:

# 数值型字段:用中位数填充(抗异常值能力强于均值)
df['amount'] = df['amount'].fillna(df['amount'].median())# 分类型字段:用众数或特殊标记(如"未知")填充
df['category'] = df['category'].fillna(df['category'].mode()[0])
df['city'] = df['city'].fillna('未知城市')# 时间型字段:用前后值填充(适用于时间序列数据)
df['login_time'] = df['login_time'].fillna(method='ffill')  # 向前填充
df['logout_time'] = df['logout_time'].fillna(method='bfill')  # 向后填充# 分组填充:按类别分组后,用组内均值填充(更精准)
df['score'] = df.groupby('class')['score'].transform(lambda x: x.fillna(x.mean())
)

三、异常值识别与处理

异常值(离群点)会扭曲统计结果和模型训练,需结合业务逻辑识别并处理。

1. 异常值检测方法

(1)统计法

适用于数值型字段,通过四分位距(IQR)或标准差判断:

def detect_outliers_iqr(df, col):"""用IQR法检测异常值"""q1 = df[col].quantile(0.25)q3 = df[col].quantile(0.75)iqr = q3 - q1lower_bound = q1 - 1.5 * iqrupper_bound = q3 + 1.5 * iqrreturn (df[col] < lower_bound) | (df[col] > upper_bound)# 检测"金额"字段的异常值
df['is_amount_outlier'] = detect_outliers_iqr(df, 'amount')
print(f"异常值比例:{df['is_amount_outlier'].mean():.2%}")
(2)业务规则法

基于领域知识判断,如订单金额不能为负、年龄不能超过150岁:

# 检测金额为负的异常值
df['is_invalid_amount'] = df['amount'] < 0# 检测年龄不合理的记录
df['is_invalid_age'] = (df['age'] < 0) | (df['age'] > 150)

2. 异常值处理策略

# 1. 修正明显错误(如金额为负可能是符号错误)
df.loc[df['amount'] < 0, 'amount'] = df.loc[df['amount'] < 0, 'amount'].abs()# 2. 截断法(将异常值限制在合理范围内)
q1, q3 = df['amount'].quantile([0.25, 0.75])
df['amount'] = df['amount'].clip(lower=q1 - 1.5 * (q3 - q1), upper=q3 + 1.5 * (q3 - q1))# 3. 标记法(保留异常值但标记,供后续分析)
df['age'] = df['age'].mask(df['age'] > 120, np.nan)  # 用NaN标记异常年龄,后续填充

四、重复数据处理

重复数据可能导致分析结果偏误(如重复计算同一订单),需检测并去重。

1. 重复数据检测

# 检测完全重复的行
duplicate_rows = df.duplicated().sum()
print(f"完全重复的行数:{duplicate_rows}")# 检测关键字段组合重复(如同一用户同一时间的重复记录)
duplicate_combo = df.duplicated(subset=['user_id', 'login_time'], keep=False).sum()
print(f"用户-时间组合重复的记录数:{duplicate_combo}")# 查看重复样本
if duplicate_rows > 0:print("重复样本示例:")print(df[df.duplicated(keep=False)].head())

2. 重复数据处理

# 保留第一次出现的记录,删除后续重复行
df = df.drop_duplicates(keep='first')# 对关键字段组合去重,并保留金额最大的记录
df = df.sort_values('amount', ascending=False)  # 按金额降序排列
df = df.drop_duplicates(subset=['user_id', 'product_id'], keep='first')

五、数据格式转换与标准化

原始数据常存在格式混乱问题(如日期格式不统一、文本大小写混用),需标准化处理。

1. 日期时间格式转换

日期字段若以字符串形式存储,需转换为datetime类型才能进行时间运算:

# 转换日期字符串为datetime类型(支持多种格式自动识别)
df['order_date'] = pd.to_datetime(df['order_date'], errors='coerce')
# errors='coerce'将无效格式转为NaT(缺失日期)# 提取日期中的年、月、周等信息
df['order_year'] = df['order_date'].dt.year
df['order_month'] = df['order_date'].dt.month
df['is_weekend'] = df['order_date'].dt.dayofweek.isin([5, 6])  # 判断是否周末

2. 文本数据清洗

处理文本字段中的大小写、空格、特殊字符等问题:

# 去除字符串前后空格
df['product_name'] = df['product_name'].str.strip()# 统一为小写(适用于不区分大小写的场景)
df['category'] = df['category'].str.lower()# 替换特殊字符(如将"手机_"和"手机("统一为"手机")
df['category'] = df['category'].str.replace(r'[_\(\)]', '', regex=True)# 提取文本中的数字(如从"价格:99元"中提取99)
df['price'] = df['price_text'].str.extract(r'(\d+)').astype(float)

3. 数据类型转换

优化数据类型以减少内存占用,或满足分析需求:

# 将字符串ID转换为分类类型(适用于高基数但重复值多的字段)
df['user_id'] = df['user_id'].astype('category')# 将数值型字符串转换为数值类型(如"100.5"→100.5)
df['amount'] = pd.to_numeric(df['amount_str'], errors='coerce')# 将布尔值转换为0/1(便于某些模型处理)
df['is_vip'] = df['is_vip'].astype(int)

六、应用实例:完整数据清洗流程

def clean_data(df):"""完整的数据清洗函数"""print(f"原始数据形状:{df.shape}")# 1. 缺失值处理print("\n=== 处理缺失值 ===")# 删除无意义的高缺失列df = df.drop(columns=['unused_col1', 'unused_col2'])# 填充数值列和分类型列num_cols = df.select_dtypes(include=['int64', 'float64']).columnsfor col in num_cols:df[col] = df[col].fillna(df[col].median())cat_cols = df.select_dtypes(include=['object', 'category']).columnsfor col in cat_cols:df[col] = df[col].fillna(df[col].mode()[0] if not df[col].mode().empty else '未知')# 2. 异常值处理print("\n=== 处理异常值 ===")df['amount'] = df['amount'].clip(lower=0)  # 金额不能为负df['age'] = df['age'].mask((df['age'] < 0) | (df['age'] > 120), df['age'].median())# 3. 重复数据处理print("\n=== 处理重复数据 ===")df = df.drop_duplicates(subset=['order_id'], keep='first')# 4. 格式转换print("\n=== 格式转换 ===")df['order_date'] = pd.to_datetime(df['order_date'], errors='coerce')df['product_name'] = df['product_name'].str.strip().str.lower()print(f"清洗后数据形状:{df.shape}")return df# 执行清洗流程
cleaned_df = clean_data(df)

总结:数据清洗的核心原则

  1. 理解业务:数据清洗的前提是理解字段含义和业务逻辑(如“年龄为负”在业务中一定是错误)。
  2. 保留痕迹:重要的修改(如异常值替换、缺失值填充)应记录在日志中,确保可追溯。
  3. 分步验证:每完成一步清洗,都需验证结果(如检查填充后是否还有缺失值)。
  4. 自动化复用:将清洗步骤封装为函数,便于在新数据上重复使用,保证处理逻辑一致。

That’s all, thanks for reading~~
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88745.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 MacOS 上安装和配置 Kafka

消息代理是一种软件&#xff0c;充当在不同应用程序之间发送消息的中介。它的功能类似于服务器&#xff0c;从一个应用程序&#xff08;称为生产者&#xff09;接收消息&#xff0c;并将其路由到一个或多个其他应用程序&#xff08;称为消费者&#xff09;。消息代理的主要目的…

基于Leaflet调用天地图在线API的多层级地名检索实战

目录 前言 一、天地图在线检索 1、在线检索功能 2、再谈后后接口 二、Leaflet多层级实现实例 1、层级调用实现原理 2、Leaflet中多层级调用 3、成果展示 三、总结 前言 “地图是世界的索引&#xff0c;而地名则是索引中的索引。”当互联网地图进入 Web 2.0 时代&#x…

基于Prompt结构的语校解析:3H日本语学校信息建模实录(4/500)

基于Prompt结构的语校解析&#xff1a;3H日本语学校信息建模实录&#xff08;4/500&#xff09; 系列延续&#xff1a;500所日本语言学校结构数据工程 关键词&#xff1a;招生结构、JLPTEJU、国籍比例、认定校、Prompt训练集 一、我们在构建什么样的语言学校语料&#xff1f; …

Leaflet面试题及答案(61-80)

查看本专栏目录 文章目录 🟢 面试问题及答案(61-80)61. 如何在地图上显示一个动态更新的图层?62. 如何实现地图上的热力图(Heatmap)?63. 如何自定义地图控件的位置?64. 如何处理地图加载失败的情况?65. 如何实现地图的离线功能?66. 如何将地图导出为图片?67. 如何实…

MIG_IP核的时钟系统

MIG_IP核的时钟系统时钟的种类和配置时钟的种类和配置 整体框图 DDR_PHY_CLK&#xff1a;DDR3的工作频率&#xff0c;用来得到想要的线速率。假设此时钟为800M&#xff0c;那么DDR双沿采样&#xff0c;线速率为1600Mbit&#xff1b; UI_CLK&#xff1a;DDR_PHY_CLK的四分之一…

若依框架集成阿里云OSS实现文件上传优化

背景介绍 在若依框架目前的实现中&#xff0c;是把图片存储到了服务器本地的目录&#xff0c;通过服务进行访问&#xff0c;这样做存储的是比较省事&#xff0c;但是缺点也有很多&#xff1a; 硬件与网络要求&#xff1a;服务器通常需要高性能的硬件和稳定的网络环境&#xff0…

Mac如何连接惠普M126a打印机(教程篇)

这里写自定义目录标题Mac如何连接惠普M126a打印机&#xff08;教程篇&#xff09;教程配置如下&#xff1a;Mac如何连接惠普M126a打印机&#xff08;教程篇&#xff09; 惠普M126a连接Mac&#xff08;教程篇&#xff09; 教程配置如下&#xff1a; 首先&#xff0c;先获取与HP打…

感恩日记:记录生活中的美好时刻

感恩日记的landing page登录注册填写感恩事项私信可以体验一下

一扇门铃,万向感应——用 eventfd 实现零延迟通信

&#x1f50d; 本篇概要 eventfd 是 Linux 提供的一种轻量级事件通知机制。你可以把它想象成一个“计数器盒子”。它里面维护的是一个64位的计数器。写入&#xff1a;往盒子里放一些数字&#xff08;比如 1、5、10&#xff09;&#xff0c;表示有几件事发生了。读取&#xff1a…

基于Node.js的线上教学系统的设计与实现(源码+论文+调试+安装+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。系统背景近年来&#xff0c;全球数字化浪潮的推进与教育公平化需求的增长&#xff0c;促使线上教学迎…

互斥锁详解(操作系统os)

1. 互斥锁 (Mutex) - 档案室的“智能锁”首先&#xff0c;我们给之前讨论的那些“锁”一个正式的名字&#xff1a;互斥锁 (Mutex)。概念&#xff1a;你可以把它简单理解成档案室门上的一把“智能锁”。它只有两种状态&#xff1a;locked (已上锁) 或 unlocked (未上锁)。操作&a…

自动润滑系统:从 “盲目养护“ 到智能精注的工业运维革命

​在工业运维的漫长历史中&#xff0c;传统润滑模式如同"定时喂饭"——无论设备实际需求&#xff0c;仅凭经验或固定周期执行润滑作业。这种模式埋下两大隐患&#xff1a;过度润滑&#xff1a;某汽车生产线曾因季度性强制润滑&#xff0c;每年浪费1.2吨润滑脂&#x…

【Java八股文总结 — 包学会】(二)计算机网络

1.一条url输入到浏览器最后显示页面的过程 URL解析与处理 浏览器解析URL&#xff08;如https://www.example.com/page&#xff09; 分离协议&#xff08;https&#xff09;、域名&#xff08;www.example.com&#xff09;和资源路径&#xff08;/page&#xff09; 检查HSTS预加…

力扣61.旋转链表

给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。示例 1&#xff1a;输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1,2,3]示例 2&#xff1a;输入&#xff1a;head [0,1,2], k 4 输出&#xff1a;[2,0,1]提示…

深度剖析:std::vector 内存机制与 push_back 扩容策略

深度剖析&#xff1a;std::vector 内存机制与 push_back 扩容策略 1. std::vector 核心内部结构 #mermaid-svg-8HOj3MqsD6UVgEeA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8HOj3MqsD6UVgEeA .error-icon{fill:…

GROW领导力模型

GROW领导力模型是由英国教练格雷厄姆亚历山大&#xff08;Graham Alexander&#xff09;、艾伦Fine和约翰惠特默&#xff08;John Whitmore&#xff09;在20世纪80年代提出的&#xff0c;最初用于体育教练领域&#xff0c;后来被广泛应用于企业管理、领导力发展和个人成长中。它…

打破并发瓶颈:虚拟线程实现详解与传统线程模型的性能对比

目录 一、定义与特性 二、虚拟线程实现 2.1 使用 Thread.startVirtualThread() 创建 2.2 使用 Thread.ofVirtual() 创建 2.3 使用 ThreadFactory 创建 2.4 使用 Executors.newVirtualThreadPerTaskExecutor()创建 三、虚拟线程和普通线程的区别 3.1 线程管理方式不同 3…

“28项评测23项SOTA——GLM-4.1V-9B-Thinking本地部署教程:10B级视觉语言模型的性能天花板!

一、模型介绍 GLM-4.1V-9B-Thinking是由智谱AI联合清华大学团队推出的多模态大模型&#xff0c;以GLM-4-9B-0414基座模型为底&#xff0c;通过引入“思维链推理机制”和“课程采样强化学习策略”&#xff08;Reinforcement Learning with Curriculum Sampling&#xff09;&…

推荐系统-Random算法

Random算法总结引言 在推荐系统研究与应用中&#xff0c;我们常常需要一些简单的基线算法来衡量更复杂算法的性能提升。Random&#xff08;随机推荐&#xff09;算法是最基础的基线方法之一&#xff0c;它通过随机生成评分来模拟用户对物品的偏好。虽然这种方法看似简单&#x…

Django--02模型和管理站点

Django–02模型与站点管理 Part 2: Models and the admin site 本教程承接Django–01的内容。我们将设置数据库、创建你的第一个模型&#xff0c;并快速了解 Django 自动生成的管理站点。 文章目录Django--02模型与站点管理前言一、设置数据库1.1 参考文档链接1.2 默认设置1.3…