使用 Pandas 进行数据标准化:全面指南
在数据分析和机器学习领域,数据标准化是一个关键的预处理步骤。它能够帮助我们消除不同特征之间量纲的影响,确保模型能够公平地对待每个特征,从而提升模型的性能和稳定性。本文将深入探讨如何使用 Python 的 pandas 库进行数据标准化,涵盖各种实用技巧和最佳实践。
一、什么是数据标准化?
数据标准化是指将数据按比例缩放,使之落入一个特定的区间。标准化的核心目标是将不同特征的取值范围统一到相似的尺度上,从而避免模型对数值范围较大的特征产生过度依赖。常见的标准化方法有以下几种:
- Min-Max 标准化:将数据缩放到 0 到 1 之间。
- Z-Score 标准化:将数据转换为均值为 0,标准差为 1 的分布。
- Robust 标准化:使用中位数和四分位数范围进行标准化,对异常值具有较强的鲁棒性。
- 单位长度标准化:将每个样本缩放到单位长度(范数为 1)。
二、为什么需要数据标准化?
在实际应用中,不同特征往往具有不同的量纲和取值范围。例如:
- 身高可能在 150-200 厘米之间
- 体重可能在 50-100 公斤之间
- 收入可能在 3000-50000 元之间
如果直接使用这些数据进行分析或建模,模型可能会过度关注数值范围较大的特征(如收入),而忽略了数值范围较小的特征(如身高)。数据标准化可以解决这个问题,让所有特征在模型中具有相同的重要性。
此外,标准化还能带来以下好处:
- 加速模型收敛:在梯度下降等优化算法中,标准化可以加快收敛速度。
- 提高模型精度:某些算法(如 KNN、SVM)对特征尺度非常敏感,标准化可以显著提升这些算法的性能。
- 增强模型稳定性:标准化可以减少异常值对模型的影响。
三、使用 Pandas 实现数据标准化
1. Min-Max 标准化
Min-Max 标准化是最常见的标准化方法之一,它将数据缩放到 0 到 1 之间。公式为:
\(x_{scaled} = \frac{x - x_{min}}{x_{max} - x_{min}}\)
下面是使用 pandas 实现 Min-Max 标准化的代码:
python
运行
import pandas as pd
# 创建示例数据
data = {
'身高(cm)': [175, 160, 180, 155, 190],
'体重(kg)': [70, 55, 80, 50, 90],
'收入(元)': [8000, 5000, 12000, 4000, 20000]
}
df = pd.DataFrame(data)
# 实现Min-Max标准化
def min_max_scaling(column):
return (column - column.min()) / (column.max() - column.min())
# 对每一列进行标准化
df_scaled = df.apply(min_max_scaling)
print("原始数据:")
print(df)
print("\nMin-Max标准化后的数据:")
print(df_scaled)
2. Z-Score 标准化
Z-Score 标准化将数据转换为均值为 0,标准差为 1 的分布。公式为:
\(x_{scaled} = \frac{x - \mu}{\sigma}\)
其中,\(\mu\)是均值,\(\sigma\)是标准差。
下面是使用 pandas 实现 Z-Score 标准化的代码:
python
运行
import pandas as pd
# 创建示例数据
data = {
'身高(cm)': [175, 160, 180, 155, 190],
'体重(kg)': [70, 55, 80, 50, 90],
'收入(元)': [8000, 5000, 12000, 4000, 20000]
}
df = pd.DataFrame(data)
# 实现Z-Score标准化
def z_score_scaling(column):
return (column - column.mean()) / column.std()
# 对每一列进行标准化
df_scaled = df.apply(z_score_scaling)
print("原始数据:")
print(df)
print("\nZ-Score标准化后的数据:")
print(df_scaled)
3. Robust 标准化
Robust 标准化使用中位数和四分位数范围进行标准化,对异常值具有较强的鲁棒性。公式为:
\(x_{scaled} = \frac{x - median}{IQR}\)
其中,median是中位数,IQR是四分位数范围(第 75 百分位数与第 25 百分位数的差值)。
下面是使用 pandas 实现 Robust 标准化的代码:
python
运行
import pandas as pd
# 创建示例数据(包含异常值)
data = {
'身高(cm)': [175, 160, 180, 155, 190, 220], # 220是异常值
'体重(kg)': [70, 55, 80, 50, 90, 150], # 150是异常值
'收入(元)': [8000, 5000, 12000, 4000, 20000, 100000] # 100000是异常值
}
df = pd.DataFrame(data)
# 实现Robust标准化
def robust_scaling(column):
median = column.median()
q1 = column.quantile(0.25)
q3 = column.quantile(0.75)
iqr = q3 - q1
return (column - median) / iqr
# 对每一列进行标准化
df_scaled = df.apply(robust_scaling)
print("原始数据:")
print(df)
print("\nRobust标准化后的数据:")
print(df_scaled)
四、处理特定列或排除某些列
在实际应用中,我们可能只需要对某些列进行标准化,或者排除某些列不进行标准化。下面是几种常见的处理方法:
1. 只对特定列进行标准化
python
运行
# 只对身高列进行Min-Max标准化
df['身高(cm)_scaled'] = min_max_scaling(df['身高(cm)'])
# 只对体重列进行Z-Score标准化
df['体重(kg)_scaled'] = z_score_scaling(df['体重(kg)'])
# 只对收入列进行Robust标准化
df['收入(元)_scaled'] = robust_scaling(df['收入(元)'])
print(df)
2. 排除某些列不进行标准化
python
运行
# 假设我们有一个包含性别列的数据集,性别列不需要标准化
data = {
'身高(cm)': [175, 160, 180, 155],
'体重(kg)': [70, 55, 80, 50],
'性别': ['男', '女', '男', '女']
}
df = pd.DataFrame(data)
# 选择需要标准化的列(数值列)
numeric_columns = df.select_dtypes(include=['float64', 'int64']).columns
# 对数值列进行Z-Score标准化
df[numeric_columns] = df[numeric_columns].apply(z_score_scaling)
print(df)
3. 使用 for 循环处理多列
python
运行
# 创建示例数据
data = {
'身高(cm)': [175, 160, 180, 155, 190],
'体重(kg)': [70, 55, 80, 50, 90],
'收入(元)': [8000, 5000, 12000, 4000, 20000]
}
df = pd.DataFrame(data)
# 对每一列进行Min-Max标准化,并添加"_scaled"后缀
for column in df.columns:
df[f'{column}_scaled'] = min_max_scaling(df[column])
print(df)
五、使用 sklearn 进行更高效的标准化
虽然 pandas 可以方便地实现数据标准化,但对于大规模数据集或需要更复杂的标准化方法时,使用 scikit-learn 库会更加高效。下面是使用 sklearn 进行标准化的示例:
python
运行
import pandas as pd
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
# 创建示例数据
data = {
'身高(cm)': [175, 160, 180, 155, 190],
'体重(kg)': [70, 55, 80, 50, 90],
'收入(元)': [8000, 5000, 12000, 4000, 20000]
}
df = pd.DataFrame(data)
# 创建Min-Max标准化器
min_max_scaler = MinMaxScaler()
# 创建Z-Score标准化器
standard_scaler = StandardScaler()
# 创建Robust标准化器
robust_scaler = RobustScaler()
# 对数据进行Min-Max标准化
df_min_max = pd.DataFrame(min_max_scaler.fit_transform(df), columns=df.columns)
# 对数据进行Z-Score标准化
df_z_score = pd.DataFrame(standard_scaler.fit_transform(df), columns=df.columns)
# 对数据进行Robust标准化
df_robust = pd.DataFrame(robust_scaler.fit_transform(df), columns=df.columns)
print("Min-Max标准化后的数据:")
print(df_min_max)
print("\nZ-Score标准化后的数据:")
print(df_z_score)
print("\nRobust标准化后的数据:")
print(df_robust)
六、标准化方法的选择指南
在实际应用中,如何选择合适的标准化方法呢?以下是一些参考指南:
| 标准化方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Min-Max 标准化 | 数据分布未知或需要保留数据的原始分布 | 简单易懂,适合神经网络 | 对异常值敏感 |
| Z-Score 标准化 | 数据符合正态分布或需要标准化后的数据具有零均值和单位方差 | 适合大多数机器学习算法 | 对异常值敏感 |
| Robust 标准化 | 数据包含大量异常值 | 对异常值具有较强的鲁棒性 | 不适合需要保留数据原始分布的场景 |
| 单位长度标准化 | 用于基于距离的算法(如 KNN、SVM) | 保留了数据的方向信息 | 不适合需要保留数据大小信息的场景 |
七、常见问题与解决方案
1. 处理包含 NaN 值的数据
python
运行
import pandas as pd
import numpy as np
# 创建包含NaN值的示例数据
data = {
'身高(cm)': [175, 160, np.nan, 155, 190],
'体重(kg)': [70, np.nan, 80, 50, 90],
'收入(元)': [8000, 5000, 12000, np.nan, 20000]
}
df = pd.DataFrame(data)
# 在标准化之前填充NaN值
df_filled = df.fillna(df.mean()) # 使用均值填充
# 对填充后的数据进行Z-Score标准化
df_scaled = df_filled.apply(z_score_scaling)
print("填充后的数据:")
print(df_filled)
print("\n标准化后的数据:")
print(df_scaled)
2. 标准化训练集和测试集
在机器学习中,我们通常需要分别对训练集和测试集进行标准化。需要注意的是,测试集的标准化参数必须来自训练集,以避免数据泄露。
python
运行
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 创建示例数据
data = {
'身高(cm)': [175, 160, 180, 155, 190, 170, 185, 165],
'体重(kg)': [70, 55, 80, 50, 90, 65, 85, 60],
'收入(元)': [8000, 5000, 12000, 4000, 20000, 7000, 15000, 6000]
}
df = pd.DataFrame(data)
# 划分训练集和测试集
X_train, X_test = train_test_split(df, test_size=0.3, random_state=42)
# 创建Z-Score标准化器
scaler = StandardScaler()
# 使用训练集的数据拟合标准化器
scaler.fit(X_train)
# 对训练集和测试集分别进行标准化
X_train_scaled = pd.DataFrame(scaler.transform(X_train), columns=X_train.columns)
X_test_scaled = pd.DataFrame(scaler.transform(X_test), columns=X_test.columns)
print("训练集标准化后的数据:")
print(X_train_scaled)
print("\n测试集标准化后的数据:")
print(X_test_scaled)
八、可视化标准化效果
下面通过可视化来直观地比较不同标准化方法的效果:
python
运行
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
# 创建示例数据
data = {
'身高(cm)': [175, 160, 180, 155, 190, 170, 185, 165],
'体重(kg)': [70, 55, 80, 50, 90, 65, 85, 60],
'收入(元)': [8000, 5000, 12000, 4000, 20000, 7000, 15000, 6000]
}
df = pd.DataFrame(data)
# 创建标准化器
min_max_scaler = MinMaxScaler()
standard_scaler = StandardScaler()
robust_scaler = RobustScaler()
# 标准化数据
df_min_max = pd.DataFrame(min_max_scaler.fit_transform(df), columns=df.columns)
df_z_score = pd.DataFrame(standard_scaler.fit_transform(df), columns=df.columns)
df_robust = pd.DataFrame(robust_scaler.fit_transform(df), columns=df.columns)
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
# 创建画布
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 绘制原始数据
sns.boxplot(data=df, ax=axes[0, 0])
axes[0, 0].set_title('原始数据')
# 绘制Min-Max标准化后的数据
sns.boxplot(data=df_min_max, ax=axes[0, 1])
axes[0, 1].set_title('Min-Max标准化后')
# 绘制Z-Score标准化后的数据
sns.boxplot(data=df_z_score, ax=axes[1, 0])
axes[1, 0].set_title('Z-Score标准化后')
# 绘制Robust标准化后的数据
sns.boxplot(data=df_robust, ax=axes[1, 1])
axes[1, 1].set_title('Robust标准化后')
plt.tight_layout()
plt.show()
九、总结
数据标准化是数据预处理的重要步骤,它能够消除不同特征之间量纲的影响,提高模型的性能和稳定性。本文介绍了四种常见的标准化方法:Min-Max 标准化、Z-Score 标准化、Robust 标准化和单位长度标准化,并展示了如何使用 pandas 和 sklearn 库实现这些方法。
在实际应用中,你可以根据数据的特点和模型的需求选择合适的标准化方法。同时,要注意处理数据中的异常值和缺失值,以及正确地对训练集和测试集进行标准化。
希望本文能够帮助你更好地理解和应用数据标准化技术!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)