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

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

个人主页-爱因斯晨

文章专栏-Python学习

在这里插入图片描述

文章目录

前言

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

了解数据清洗

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

数据清洗的步骤

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方法检测异常值defdetect_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)ifnot outliers.empty:print(f"{col}列异常值数量:{len(outliers)}")# 方法1:删除异常值# df = df.drop(outliers.index)# 方法2:截断异常值(替换为边界值) df.loc[df[col]< lower, col]= lower df.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 StandardScaler scaler = 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 MinMaxScaler scaler = 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 - Q1 lower_bound = Q1 -1.5* IQR upper_bound = Q3 +1.5* IQR df = 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("数据的前几行")

处理结果:

在这里插入图片描述


在这里插入图片描述

总结

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

Read more

Flutter 组件 meeting_place_core 的适配 鸿蒙Harmony 实战 - 驾驭分布式会议引擎、实现鸿蒙端高性能协作空间与复杂信令分发方案

Flutter 组件 meeting_place_core 的适配 鸿蒙Harmony 实战 - 驾驭分布式会议引擎、实现鸿蒙端高性能协作空间与复杂信令分发方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 meeting_place_core 的适配 鸿蒙Harmony 实战 - 驾驭分布式会议引擎、实现鸿蒙端高性能协作空间与复杂信令分发方案 前言 在后疫情时代的协同办公浪潮中,视频会议已经从单一的垂直应用演变为鸿蒙(OpenHarmony)生态中“泛在协作”的核心基础设施。当你在鸿蒙平板上开启一场跨国技术评审,或者在鸿蒙车机上紧急连线公司晨会时,支撑这一切流畅运行的,是底层极其复杂的会议核心引擎。 meeting_place_core 是一套工业级的、专为多端同步设计的会议核心抽象包。它不负责 UI 渲染,而是专注于房间管理(Room Management)、成员状态流转、信令推送及媒体流的逻辑编排。 适配到鸿蒙平台后,结合鸿蒙强大的分布式能力,meeting_place_core 能让你的 App 轻松实现“手机开会,大屏投映,

By Ne0inhk
从海量时序数据到无人值守:数据库在新能源集控系统中的架构实践

从海量时序数据到无人值守:数据库在新能源集控系统中的架构实践

文章目录 * 引言 * 关于金仓数据库 * 金仓数据库在新能源行业的技术解读 * 1. 应对海量时序数据:分区存储与高效查询 * 2. 支撑高并发访问:读写分离与自治调优 * 3. 保障业务连续性:跨地域高可用与容灾 * 4. 实现平滑迁移:高度兼容与自动化工具 * 案例分析:金仓数据库赋能新能源智慧运维 * 案例一:中广核新能源生产运维系统——应对“整合、高并发、高可用”三大挑战 * 案例二:国家能源集团龙源电力——186个新能源场站集控系统国产化替代 * 案例三:国家电投集团甘肃新能源——“无人值守”风电场集控系统 * 结语 引言 谈到“双碳”与能源革命,风电,光伏这些新能源产业显然是当下最为炙手可热的风口,若想在该赛道跑得更远,更快,数字化和智能化转型并非可选,而是必备功课,要知道,从远程操控成千上万台风电机组,到及时分析大量的设备数据,直至把整个生产运维流程管理得井井有条,哪一步能离开稳定,高效且安全的数据“大后方”

By Ne0inhk
Flutter 组件 tw_queue 的适配 鸿蒙Harmony 实战 - 驾驭分布式高并发任务队列、实现鸿蒙端流式任务调度与生产级持久化断点续传方案

Flutter 组件 tw_queue 的适配 鸿蒙Harmony 实战 - 驾驭分布式高并发任务队列、实现鸿蒙端流式任务调度与生产级持久化断点续传方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 tw_queue 的适配 鸿蒙Harmony 实战 - 驾驭分布式高并发任务队列、实现鸿蒙端流式任务调度与生产级持久化断点续传方案 前言 在鸿蒙(OpenHarmony)生态的工业级应用或是大型协同办公软件中,我们时刻面临着“海量任务堆积”的挑战。例如:在 0307 批次的博文自动化生产线中,160 个文件、上百万字的博文生成、图片压缩以及云端同步任务,如果全部无脑地开启并发,会瞬间撑爆鸿蒙设备的内存句柄(OOM),同时也可能触发后端的限流封禁。 我们需要的是一个具备“理智”与“弹性”的交通管制系统。 tw_queue 是一套专为高性能、分布式任务调度设计的流水线工具。它不仅能控制并发数(Concurrency),更具备了任务持久化、失败自动重试、甚至是带权重的优先级调度能力。在鸿蒙适配实战中,tw_

By Ne0inhk
Flutter 组件 ubuntu_service 适配鸿蒙 HarmonyOS 实战:底层系统服务治理,构建鸿蒙 Linux 子系统与守护进程交互架构

Flutter 组件 ubuntu_service 适配鸿蒙 HarmonyOS 实战:底层系统服务治理,构建鸿蒙 Linux 子系统与守护进程交互架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 ubuntu_service 适配鸿蒙 HarmonyOS 实战:底层系统服务治理,构建鸿蒙 Linux 子系统与守护进程交互架构 前言 在鸿蒙(OpenHarmony)生态迈向工业互联、智能车载及深度客制化终端的背景下,如何实现 Flutter 应用对底层 Linux 服务(如 Systemd/DBus)的受控访问、在端侧治理长驻守护进程,已成为提升应用系统级集成能力的“技术门槛”。在鸿蒙设备这类强调内核级安全防护与微内核分布式调度的环境下,如果应用仅能实现表层 UI 的交互,而无法感知、重启或监控底层硬件驱动相关的后台服务,就无法在大屏中控、工业看板或服务器管理设备中胜任“控制塔”的角色。 我们需要一种能够穿透沙箱壁垒、支持 DBus 通信协议且具备高可靠服务状态感知能力的系统治理方案。 ubuntu_service 为

By Ne0inhk