使用Python进行数据清洗:技术实践与代码示例
在数据科学和机器学习的整个流程中,数据清洗(Data Cleaning) 是最为关键的一环。据估计,数据科学家大约有70%的时间都花在了数据清洗和预处理上。无论模型多么先进,如果输入的数据质量差、存在缺失值或异常值,最终的模型效果都会大打折扣。
本文将围绕如何使用 Python 进行高效的数据清洗,涵盖常见的清洗任务,包括:
缺失值处理异常值检测与处理数据类型转换重复值删除文本清洗我们将使用 Pandas 和 NumPy 等常用的数据处理库,并通过一个完整的实战项目来演示这些技术的应用。
准备工作
首先,确保你的环境中安装了以下库:
pip install pandas numpy matplotlib seaborn
然后导入必要的模块:
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns
加载数据集
我们以一个虚构的电商用户行为数据集为例,文件为 user_behavior.csv
。
df = pd.read_csv("user_behavior.csv")print(df.head())
输出可能如下所示:
user_id age gender purchase_amount last_purchase_date is_subscribed0 101 28 Male 150.0 2023-01-15 Yes1 102 NaN Female NaN NaN No2 103 45 NaN 200.0 2023-02-20 Yes3 104 33 Male NaN 2023-03-01 NaN4 105 29 Male 180.0 2023-03-10 Yes
可以看到,数据中存在缺失值、格式错误、非数值字段等问题。
缺失值处理
1. 检查缺失值
print(df.isnull().sum())
输出:
user_id 0age 1gender 1purchase_amount 2last_purchase_date 1is_subscribed 1
2. 填充缺失值
对于数值型列,我们可以使用均值、中位数或众数填充;对于类别型列,可以使用众数或用 "Unknown" 表示。
# 填充数值列df['age'] = df['age'].fillna(df['age'].median())df['purchase_amount'] = df['purchase_amount'].fillna(df['purchase_amount'].mean())# 填充类别列df['gender'] = df['gender'].fillna(df['gender'].mode()[0])df['is_subscribed'] = df['is_subscribed'].fillna('Unknown')
3. 删除缺失值较多的行(可选)
df.dropna(subset=['last_purchase_date'], inplace=True)
异常值检测与处理
1. 使用箱线图识别异常值
sns.boxplot(x=df['purchase_amount'])plt.title("Boxplot of Purchase Amount")plt.show()
2. Z-score 方法检测异常值
from scipy import statsz_scores = stats.zscore(df['purchase_amount'])abs_z_scores = np.abs(z_scores)filtered_entries = (abs_z_scores < 3)df = df[filtered_entries]
数据类型转换
1. 将日期列转为 datetime 类型
df['last_purchase_date'] = pd.to_datetime(df['last_purchase_date'])
2. 对类别变量进行编码(Label Encoding)
from sklearn.preprocessing import LabelEncoderle = LabelEncoder()df['gender'] = le.fit_transform(df['gender'])df['is_subscribed'] = le.fit_transform(df['is_subscribed'].astype(str))
去除重复记录
df.drop_duplicates(subset=['user_id'], keep='first', inplace=True)
文本清洗(如存在)
假设我们有一个描述字段 description
,其中包含一些无意义字符或HTML标签。
import redef clean_text(text): text = re.sub('<[^<]+?>', '', str(text)) # 去除HTML标签 text = re.sub(r'[^\w\s]', '', text) # 去除非字母数字空格 text = text.lower().strip() # 转小写并去前后空格 return textdf['cleaned_description'] = df['description'].apply(clean_text)
保存清洗后的数据
df.to_csv("cleaned_user_behavior.csv", index=False)
完整代码汇总
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsfrom scipy import statsfrom sklearn.preprocessing import LabelEncoderimport re# 加载数据df = pd.read_csv("user_behavior.csv")# 查看数据print(df.head())print(df.isnull().sum())# 填充缺失值df['age'] = df['age'].fillna(df['age'].median())df['purchase_amount'] = df['purchase_amount'].fillna(df['purchase_amount'].mean())df['gender'] = df['gender'].fillna(df['gender'].mode()[0])df['is_subscribed'] = df['is_subscribed'].fillna('Unknown')# 删除缺失日期的行df.dropna(subset=['last_purchase_date'], inplace=True)# 异常值处理z_scores = stats.zscore(df['purchase_amount'])abs_z_scores = np.abs(z_scores)filtered_entries = (abs_z_scores < 3)df = df[filtered_entries]# 数据类型转换df['last_purchase_date'] = pd.to_datetime(df['last_purchase_date'])le = LabelEncoder()df['gender'] = le.fit_transform(df['gender'])df['is_subscribed'] = le.fit_transform(df['is_subscribed'].astype(str))# 去重df.drop_duplicates(subset=['user_id'], keep='first', inplace=True)# 文本清洗(如有)def clean_text(text): text = re.sub('<[^<]+?>', '', str(text)) text = re.sub(r'[^\w\s]', '', text) text = text.lower().strip() return textif 'description' in df.columns: df['cleaned_description'] = df['description'].apply(clean_text)# 保存结果df.to_csv("cleaned_user_behavior.csv", index=False)print("数据清洗完成!")
十、总结
数据清洗是一项繁琐但至关重要的工作。本文通过一个实际案例,展示了如何使用 Python 中的 Pandas、NumPy、Scikit-learn 和正则表达式等工具,对数据进行系统的清洗与预处理。
掌握这些技能不仅能提升你对数据的理解能力,也能显著提高后续建模的效果。希望这篇文章能为你在数据清洗的学习道路上提供有价值的参考。
如果你正在处理真实业务中的数据,建议结合领域知识进一步优化清洗策略。例如,在金融风控场景中,某些“异常值”可能是欺诈行为的表现,此时就不应简单剔除。
继续加油,成为一名真正的数据清洗高手吧!