机器学习:数据清洗与预处理 | Python

个人主页-爱因斯晨

文章专栏-Python学习

在这里插入图片描述

文章目录

    • 个人主页-爱因斯晨
    • 文章专栏-Python学习
  • 前言
  • 了解数据清洗
  • 数据清洗的步骤
    • 1. 环境准备与库导入
    • 2. 数据加载
    • 3. 数据初探与理解
    • 4. 缺失值处理
    • 5. 重复值处理
    • 6. 异常值处理
    • 7. 数据类型转换
    • 8. 数据标准化 / 归一化(预处理)
  • 实例实践
  • 总结

前言

我们不论在学习机器学习还是数据分析中,都会涉及很多数据。但原数据不可避免有很多杂志,为了确保结果的准确性,我们需要首先进行数据清洗和预处理。

了解数据清洗

数据清洗就像是一场数据的“大扫除”。它是从原始数据中找出并修正那些错误、不完整、重复或不一致的数据。通过数据清洗,能显著提升数据质量,为后续数据分析、挖掘和建模等工作提供准确、可靠、干净的数据基础,从而让基于数据得出的结论更具可信度和价值。

数据清洗的步骤

1. 环境准备与库导入

import pandas as pd  # 数据处理核心库
import numpy as np   # 数值计算库
import matplotlib.pyplot as plt  # 基础可视化库
import seaborn as sns  # 高级可视化库# 设置显示参数,确保中文正常显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
pd.set_option('display.max_columns', None)  # 显示所有列
pd.set_option('display.width', 1000)        # 显示宽度

函数 / 参数解释

  • import pandas as pd:导入 pandas 库并简写为 pd。pandas 是数据处理的核心工具,提供了 DataFrame 数据结构和丰富的数据操作方法。
  • plt.rcParams:设置 matplotlib 的全局参数,这里用于配置中文字体,避免图表中中文显示为乱码。
  • pd.set_option:配置 pandas 的显示选项,确保查看数据时不会截断列或内容。

2. 数据加载

# 从CSV文件加载数据
df = pd.read_csv('data.csv')# 从Excel文件加载数据(支持多工作表)
excel_file = pd.ExcelFile('data.xlsx')
df = excel_file.parse('Sheet1')  # 读取名为Sheet1的工作表# 查看数据规模
print(f"数据集规模:{df.shape[0]}行,{df.shape[1]}列")

函数解释

  • pd.read_csv():读取 CSV 文件并返回 DataFrame 对象。
    • 常用参数:sep(分隔符,默认逗号)、header(表头行索引,默认 0)、na_values(指定缺失值标识)、usecols(指定读取的列)
    • 示例:pd.read_csv('data.csv', sep=';', na_values=['NA', 'missing'])
  • pd.ExcelFile()parse()
    • pd.ExcelFile():创建 Excel 文件对象,用于高效读取包含多个工作表的 Excel 文件
    • parse():从 ExcelFile 对象中读取指定工作表,参数sheet_name指定工作表名称或索引

3. 数据初探与理解

# 查看数据基本信息
print("数据基本信息:")
df.info()# 查看前5行数据
print("\n数据前5行:")
print(df.head())# 查看数值型列的统计描述
print("\n数值型列统计描述:")
print(df.describe())# 查看类别型列的取值分布
print("\n类别型列取值分布:")
for col in df.select_dtypes(include=['object', 'category']).columns:print(f"\n{col}列分布:")print(df[col].value_counts())

函数解释

  • info():查看 DataFrame 的基本信息,包括索引类型、列信息、数据类型、非空值数量和内存占用。
  • head(n):返回前 n 行数据(默认 n=5),用于快速预览数据内容。对应的tail(n)返回后 n 行。
  • describe():生成数值型列的统计摘要,包括计数、均值、标准差、最值和四分位数。
  • select_dtypes(include=[]):筛选指定数据类型的列,include=['object', 'category']用于筛选类别型列。
  • value_counts():计算类别型列中每个取值的出现次数,用于了解数据分布。

4. 缺失值处理

# 1. 检测缺失值
missing_count = df.isnull().sum()  # 计算每列缺失值数量
missing_ratio = missing_count / len(df)  # 计算缺失比例
missing_df = pd.DataFrame({'缺失值数量': missing_count,'缺失比例': missing_ratio
})
print("缺失值统计:")
print(missing_df[missing_df['缺失值数量'] > 0])  # 只显示有缺失值的列# 2. 处理缺失值
# 方法1:删除缺失值(适用于缺失比例极低的情况)
df_drop = df.dropna(axis=0)  # 按行删除,axis=1按列删除# 方法2:填充缺失值
# 数值型列用均值/中位数填充
df['数值列1'] = df['数值列1'].fillna(df['数值列1'].mean())  # 均值填充
df['数值列2'] = df['数值列2'].fillna(df['数值列2'].median())  # 中位数填充# 类别型列用众数填充
df['类别列1'] = df['类别列1'].fillna(df['类别列1'].mode()[0])  # 众数填充# 方法3:用前后值填充(适用于时间序列)
df['时间序列列'] = df['时间序列列'].fillna(method='ffill')  # 向前填充
# df['时间序列列'] = df['时间序列列'].fillna(method='bfill')  # 向后填充

函数解释

  • isnull():返回布尔型 DataFrame,标记每个元素是否为缺失值(NaN)。
  • sum():对isnull()的结果求和,得到每列缺失值数量。
  • dropna(axis=0):删除包含缺失值的行(axis=0)或列(axis=1)。
    • 常用参数:how='any'(默认,任何缺失值即删除)、how='all'(所有值都缺失才删除)
  • fillna():填充缺失值,支持固定值、统计量(均值 / 中位数 / 众数)和前后值填充。

5. 重复值处理

# 1. 检测重复行
duplicate_rows = df.duplicated()  # 返回布尔型Series,标记是否为重复行
print(f"重复行数量:{duplicate_rows.sum()}")# 2. 查看重复行内容
if duplicate_rows.sum() > 0:print("重复行内容:")print(df[duplicate_rows])# 3. 删除重复行
df_clean = df.drop_duplicates(keep='first')  # 保留第一次出现的行
# df_clean = df.drop_duplicates(keep='last')  # 保留最后一次出现的行
# df_clean = df.drop_duplicates(keep=False)   # 删除所有重复行print(f"删除重复行后:{df_clean.shape[0]}行")

函数解释

  • duplicated():检测重复行,返回布尔型 Series。
    • 参数subset=['col1', 'col2']:指定用于判断重复的列
    • 默认保留第一次出现的行,标记后续重复行为 True
  • drop_duplicates():删除重复行,参数keep控制保留策略:
    • keep='first':保留第一次出现的行(默认)
    • keep='last':保留最后一次出现的行
    • keep=False:删除所有重复行

6. 异常值处理

# 1. 绘制箱线图可视化异常值
plt.figure(figsize=(12, 6))
sns.boxplot(data=df.select_dtypes(include=np.number))  # 只对数值列绘图
plt.title('数值列箱线图(用于检测异常值)')
plt.tight_layout()
plt.show()# 2. 使用IQR方法检测异常值
def detect_outliers(df, col):"""检测指定列的异常值"""Q1 = df[col].quantile(0.25)  # 下四分位数Q3 = df[col].quantile(0.75)  # 上四分位数IQR = Q3 - Q1  # 四分位距lower_bound = Q1 - 1.5 * IQR  # 下界upper_bound = Q3 + 1.5 * IQR  # 上界outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]return outliers, lower_bound, upper_bound# 处理每个数值列的异常值
for col in df.select_dtypes(include=np.number).columns:outliers, lower, upper = detect_outliers(df, col)if not outliers.empty:print(f"{col}列异常值数量:{len(outliers)}")# 方法1:删除异常值# df = df.drop(outliers.index)# 方法2:截断异常值(替换为边界值)df.loc[df[col] < lower, col] = lowerdf.loc[df[col] > upper, col] = upper

函数解释

  • sns.boxplot():绘制箱线图,直观展示数据分布和异常值。箱线图中,超出上下须线(Q1-1.5IQR 和 Q3+1.5IQR)的点被视为异常值。
  • quantile(q):计算分位数,q=0.25 表示下四分位数(Q1),q=0.75 表示上四分位数(Q3)。
  • 异常值处理策略:删除(适用于错误数据)、截断(替换为边界值)、转换(如对数转换)。

7. 数据类型转换

# 查看当前数据类型
print("原始数据类型:")
print(df.dtypes)# 1. 转换为数值类型(处理字符串格式的数值)
df['数值列'] = pd.to_numeric(df['数值列'], errors='coerce')  # 无法转换的值变为NaN# 2. 转换为日期类型
df['日期列'] = pd.to_datetime(df['日期列'], format='%Y-%m-%d')  # 指定格式加速转换# 3. 转换为类别类型(适用于取值有限的字符串列)
df['类别列'] = df['类别列'].astype('category')# 查看转换后的数据类型
print("\n转换后数据类型:")
print(df.dtypes)

函数解释

  • dtypes:查看各列的数据类型。
  • pd.to_numeric():将列转换为数值类型,errors='coerce'参数将无法转换的值设为 NaN。
  • pd.to_datetime():将列转换为日期时间类型,format参数指定日期格式。
  • astype('category'):将字符串列转换为类别类型,减少内存占用并提高效率。

8. 数据标准化 / 归一化(预处理)

# 1. 标准化(Z-score标准化,使均值为0,标准差为1)
from sklearn.preprocessing import StandardScalerscaler = StandardScaler()
numeric_cols = df.select_dtypes(include=np.number).columns
df[numeric_cols] = scaler.fit_transform(df[numeric_cols])# 2. 归一化(Min-Max归一化,将值缩放到[0,1]范围)
from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()
df[numeric_cols] = scaler.fit_transform(df[numeric_cols])# 查看处理后的统计描述
print("标准化/归一化后统计描述:")
print(df[numeric_cols].describe())

函数解释

  • StandardScaler():Z-score 标准化,公式为:(x’ = (x - \mu) / \sigma),其中(\mu)是均值,(\sigma)是标准差。适用于数据近似正态分布的情况。
  • MinMaxScaler():Min-Max 归一化,将值缩放到 [0,1] 范围,公式为:(x’ = (x - \min) / (\max - \min))。适用于需要将数据限制在特定范围的场景。

实例实践

以鸢尾花数据集为例

原数据集:在资源绑定中

#导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns#设置显示选项
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)# 使用原始字符串处理文件路径
excel_file = r'C:\Users\einsc\PycharmProjects\PythonProject\.venv\share\yuan\iris_dataset.xlsx'#获取表名
sheet_names = pd.ExcelFile(excel_file).sheet_names
print(sheet_names)#读取数据
df = pd.ExcelFile(excel_file).parse('Sheet1')print("数据基本信息")
df.info()
rows, columns = df.shape
print(f"数据的行数: {rows}")
print(f"数据的列数: {columns}")
print("数据的前几行")
print(df.head())# 处理缺失值
print("缺失值统计:")
print(df.isnull().sum())
# 若存在缺失值,这里选择用列均值填充数值型列,用众数填充类别型列
for col in df.columns:if df[col].dtype == 'object':df[col] = df[col].fillna(df[col].mode()[0])else:df[col] = df[col].fillna(df[col].mean())# 处理重复值
print("重复值数量:", df.duplicated().sum())
# 删除重复值
df = df.drop_duplicates()# 处理异常值(使用 IQR 方法)
numerical_columns = df.select_dtypes(include=[np.number]).columns
for col in numerical_columns:Q1 = df[col].quantile(0.25)Q3 = df[col].quantile(0.75)IQR = Q3 - Q1lower_bound = Q1 - 1.5 * IQRupper_bound = Q3 + 1.5 * IQRdf = df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]# 重置索引
df = df.reset_index(drop=True)print("清洗后数据基本信息")
df.info()
print("清洗后数据行数: ", df.shape[0])
print("清洗后数据列数: ", df.shape[1])# 定义保存路径
output_file = r'C:\Users\einsc\PycharmProjects\PythonProject\.venv\share\yuan\iris_dataset_cleaned.xlsx'
# 将清洗后的数据保存到新的 Excel 文件
df.to_excel(output_file, index=False, sheet_name='CleanedData')
print(f"清洗后的数据已保存到 {output_file}")
print("数据的前几行")

处理结果:
在这里插入图片描述
在这里插入图片描述

总结

本文聚焦机器学习中的数据清洗与预处理。先阐述其重要性,如同为数据“大扫除”,能提升数据质量、保障结论可靠。接着分八个步骤详细讲解,从环境准备与库导入,到数据加载、初探,再到缺失值、重复值、异常值处理,以及数据类型转换和标准化/归一化,每个步骤都有代码示例和函数解释。最后以鸢尾花数据集为例实践,经各环节处理后保存清洗数据。整体内容系统全面,理论与实践结合,助读者掌握数据清洗与预处理的关键要点和操作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【代码随想录】+ leetcode hot100:栈与队列算法专题总结、单调栈

大家好&#xff0c;我是此林。 今天分享的是【代码随想录】栈与队列算法专题总结&#xff0c;分享刷算法的心得体会。 1. 用栈实现队列、用队列实现栈 232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09;…

每次启动服务器都要手动选择启动项

存在的问题 如下图所示&#xff1a; 每次启动服务器的时候&#xff0c;都需要手动将光标选择到第二条&#xff0c;敲回车&#xff0c;才能正常启动系统。从图片可以看到&#xff0c;这是一个 GRUB 启动菜单&#xff0c;显示了三个选项&#xff1a; CentOS Linux (3.10.0-1160.1…

C#.NET BackgroundService 详解

简介 BackgroundService 是 .NET Core 引入的用于实现长时间运行后台任务的基类&#xff0c;位于 Microsoft.Extensions.Hosting 命名空间。它是构建 Worker Service 和后台处理的核心组件。 为什么使用 BackgroundService&#xff1f;优雅的生命周期管理&#xff1a;自动处理启…

数据结构与算法学习(一)

1 字典树&#xff08;前缀树&#xff09; 前缀树是N叉树的一种特殊形式。通常来说&#xff0c;一个前缀树是用来存储字符串的。前缀树的每一个节点代表一个字符串&#xff08;前缀&#xff09;。每一个节点会有多个子节点&#xff0c;通往不同子节点的路径上有着不同的字符。子…

LeetCode Hot 100 二叉树的最大深度

给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。示例 1&#xff1a;输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a;输入&#xff1a;root [1,null,2] 输出&#…

Flutter基础(前端教程①①-底部导航栏)

1. 主页面&#xff08;BottomNavBarPage&#xff09;用 _currentBarIndex 记录当前选中的导航索引&#xff08;默认 0&#xff0c;即首页&#xff09;。用 IndexedStack 管理 4 个页面&#xff0c;通过 _currentBarIndex 控制显示哪个页面&#xff08;比如索引 1 就显示 NodePa…

HTML 入门教程:从零开始学习网页开发基础

一、HTML简介 1.1 什么是HTML&#xff1f; HTML全称是Hyper Text Markup Language&#xff08;超文本标记语言&#xff09;&#xff0c;由Tim Berners-Lee和同事Daniel W. Connolly于1990年创立。它是一种用于创建网页的标准标记语言&#xff0c;而不是编程语言。 1.2 HTML的…

LeetCode Hot100【4. 寻找两个正序数组的中位数】

4. 寻找两个正序数组的中位数 自己做 分析 解1&#xff1a;归并思想 class Solution { public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int sum 0;double value;queue<double> value2;int i 0, j 0;if ((nums…

JobSet:Kubernetes 分布式任务编排的统一解决方案

JobSet–Kubernetes 分布式任务编排的统一解决方案 在 Kubernetes 生态中&#xff0c;分布式机器学习训练和高性能计算&#xff08;HPC&#xff09;工作负载的编排一直是技术难点。随着大语言模型&#xff08;LLM&#xff09;等大型 AI 模型的兴起&#xff0c;单主机资源已无法…

【电脑】显示器的基础知识

显示器是计算机系统中用于显示图像、文本和其他视觉内容的重要组件。它将电子信号转化为可见的图像&#xff0c;使用户可以直观地查看和操作数据。以下是关于显示器的一些详细知识&#xff1a;1. 显示器的基本类型CRT显示器&#xff08;阴极射线管显示器&#xff09;工作原理&a…

【删库跑路】一次删除pip的所有第三方库

进入命令行&#xff0c;先list看下库存pip list导出所有的第三方库至一文件列表pip freeze >requirements.txt按照列表卸载所有库pip uninstall -r requirements.txt -y再list看下&#xff0c;可见库存已清空

19.如何将 Python 字符串转换为 Slug

如何将 Python 字符串转换为 Slug(URL 友好格式) 什么是 Slug? Slug 是一种 URL 友好、便于人类阅读的字符串。只包含小写字母、数字和连字符(-)。常见于文章标题、商品名等生成的网址路径中。例如: "Hello World!" → "hello-world"1. Slugify 的…