本文目录导读:

我来详细讲解如何使用Pandas进行数据标准化,包括几种常用的标准化方法。
准备数据
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import warnings
warnings.filterwarnings('ignore')
# 创建示例数据
data = {
'年龄': [25, 30, 35, 40, 45, 50, 55],
'收入': [5000, 8000, 12000, 15000, 20000, 25000, 30000],
'工作年限': [1, 3, 5, 7, 10, 12, 15],
'教育年限': [12, 14, 16, 16, 18, 18, 20]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("\n原始数据统计:")
print(df.describe())
Z-Score标准化(最常用)
# 方法1:使用sklearn的StandardScaler
from sklearn.preprocessing import StandardScaler
# Z-Score标准化
scaler = StandardScaler()
df_zscore = pd.DataFrame(
scaler.fit_transform(df),
columns=df.columns,
index=df.index
)
print("Z-Score标准化后的数据:")
print(df_zscore)
print("\n标准化后统计(均值≈0,标准差≈1):")
print(df_zscore.describe())
Min-Max标准化(0-1归一化)
# 方法1:使用sklearn的MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
# Min-Max归一化(0-1范围)
mm_scaler = MinMaxScaler()
df_minmax = pd.DataFrame(
mm_scaler.fit_transform(df),
columns=df.columns,
index=df.index
)
print("Min-Max标准化后的数据(0-1范围):")
print(df_minmax)
# 自定义范围(1到1)
mm_scaler_custom = MinMaxScaler(feature_range=(-1, 1))
df_minmax_custom = pd.DataFrame(
mm_scaler_custom.fit_transform(df),
columns=df.columns,
index=df.index
)
print("\nMin-Max标准化(-1到1范围):")
print(df_minmax_custom)
使用Pandas自定义标准化
# Z-Score标准化(手动实现)
df_zscore_manual = (df - df.mean()) / df.std()
print("手动Z-Score标准化:")
print(df_zscore_manual)
# Min-Max标准化(手动实现)
df_minmax_manual = (df - df.min()) / (df.max() - df.min())
print("\n手动Min-Max标准化:")
print(df_minmax_manual)
其他标准化方法
# 1. 均值归一化
df_mean_norm = (df - df.mean()) / (df.max() - df.min())
print("均值归一化:")
print(df_mean_norm)
# 2. 对数标准化(处理偏态数据)
# 注意:数据不能包含0或负数
df_log = np.log(df)
print("\n对数标准化:")
print(df_log)
# 3. 小数定标标准化
def decimal_scaling(df):
max_abs = df.abs().max()
return df / 10 ** (np.ceil(np.log10(max_abs + 1)))
df_decimal = decimal_scaling(df)
print("\n小数定标标准化:")
print(df_decimal)
完整案例:数据标准化流程
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import matplotlib.pyplot as plt
# 创建更复杂的数据集
np.random.seed(42)
data = {
'年龄': np.random.randint(20, 60, 100),
'收入': np.random.randint(3000, 50000, 100),
'工作年限': np.random.randint(0, 30, 100),
'教育年限': np.random.randint(6, 22, 100),
'消费金额': np.random.randint(100, 5000, 100)
}
df = pd.DataFrame(data)
# 1. 数据探索
print("原始数据描述统计:")
print(df.describe())
# 2. 检测异常值和缺失值
print("\n缺失值统计:")
print(df.isnull().sum())
# 3. 选择标准化方法
def normalize_data(df, method='zscore'):
"""
数据标准化函数
method: 'zscore', 'minmax', 'robust'
"""
if method == 'zscore':
scaler = StandardScaler()
df_normalized = pd.DataFrame(
scaler.fit_transform(df),
columns=df.columns,
index=df.index
)
elif method == 'minmax':
scaler = MinMaxScaler()
df_normalized = pd.DataFrame(
scaler.fit_transform(df),
columns=df.columns,
index=df.index
)
elif method == 'robust':
# 稳健标准化(使用中位数和IQR)
df_normalized = (df - df.median()) / (df.quantile(0.75) - df.quantile(0.25))
else:
raise ValueError(f"不支持的标准化方法: {method}")
return df_normalized
# 4. 执行标准化
df_zscore = normalize_data(df, 'zscore')
df_minmax = normalize_data(df, 'minmax')
df_robust = normalize_data(df, 'robust')
# 5. 比较标准化效果
print("\nZ-Score标准化后统计:")
print(df_zscore.head())
print(df_zscore.describe())
print("\nMin-Max标准化后统计:")
print(df_minmax.head())
print(df_minmax.describe())
# 6. 可视化对比
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
# 原始数据分布
axes[0, 0].hist(df.values, bins=20, alpha=0.7)
axes[0, 0].set_title('原始数据分布')
axes[0, 0].set_ylabel('频数')
# Z-Score标准化
axes[0, 1].hist(df_zscore.values, bins=20, alpha=0.7)
axes[0, 1].set_title('Z-Score标准化')
# Min-Max标准化
axes[0, 2].hist(df_minmax.values, bins=20, alpha=0.7)
axes[0, 2].set_title('Min-Max标准化')
# 箱线图对比
df.boxplot(ax=axes[1, 0])
axes[1, 0].set_title('原始数据箱线图')
axes[1, 0].tick_params(axis='x', rotation=45)
df_zscore.boxplot(ax=axes[1, 1])
axes[1, 1].set_title('Z-Score箱线图')
axes[1, 1].tick_params(axis='x', rotation=45)
df_minmax.boxplot(ax=axes[1, 2])
axes[1, 2].set_title('Min-Max箱线图')
axes[1, 2].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
实际应用案例:机器学习数据预处理
# 完整的数据预处理器类
class DataPreprocessor:
def __init__(self):
self.scalers = {}
def zscore_normalize(self, df, columns=None):
"""Z-Score标准化"""
if columns is None:
columns = df.columns
df_normalized = df.copy()
for col in columns:
scaler = StandardScaler()
df_normalized[col] = scaler.fit_transform(df[[col]])
self.scalers[f'{col}_zscore'] = scaler
return df_normalized
def minmax_normalize(self, df, columns=None, feature_range=(0, 1)):
"""Min-Max标准化"""
if columns is None:
columns = df.columns
df_normalized = df.copy()
for col in columns:
scaler = MinMaxScaler(feature_range=feature_range)
df_normalized[col] = scaler.fit_transform(df[[col]])
self.scalers[f'{col}_minmax'] = scaler
return df_normalized
def inverse_transform(self, df_normalized, method='zscore'):
"""反向转换"""
df_original = df_normalized.copy()
for col in df_normalized.columns:
scaler_key = f'{col}_{method}'
if scaler_key in self.scalers:
df_original[col] = self.scalers[scaler_key].inverse_transform(
df_normalized[[col]]
)
return df_original
def pipeline_normalize(self, df, methods=None):
"""
自动选择标准化方法
对于偏态数据使用对数变换+Z-Score
对于均匀数据使用Z-Score
对于有界数据使用Min-Max
"""
if methods is None:
methods = {}
df_normalized = df.copy()
for col in df.columns:
if col in methods:
method = methods[col]
else:
# 自动判断标准化方法
skewness = df[col].skew()
if abs(skewness) > 1:
method = 'log'
elif df[col].min() >= 0 and df[col].max() <= 1:
method = 'none' # 已经是归一化数据
else:
method = 'zscore'
if method == 'zscore':
df_normalized[col] = self.zscore_normalize(df[[col]], [col])[col]
elif method == 'minmax':
df_normalized[col] = self.minmax_normalize(df[[col]], [col])[col]
elif method == 'log':
# 对数变换
df_normalized[col] = np.log1p(df[col] - df[col].min() + 1)
# 再次Z-Score标准化
scaler = StandardScaler()
df_normalized[col] = scaler.fit_transform(df_normalized[[col]])
self.scalers[f'{col}_log'] = scaler
return df_normalized
# 使用示例
preprocessor = DataPreprocessor()
# 创建示例数据
df = pd.DataFrame({
'年龄': [25, 30, 35, 40, 45],
'收入': [5000, 8000, 12000, 15000, 20000],
'消费分数': [0.1, 0.3, 0.5, 0.7, 0.9] # 已经归一化的数据
})
# 自动标准化
df_normalized = preprocessor.pipeline_normalize(df)
print("自动标准化结果:")
print(df_normalized)
# 反向转换
df_restored = preprocessor.inverse_transform(df_normalized, 'zscore')
print("\n反向转换结果:")
print(df_restored)
使用建议
- Z-Score标准化:适合大多数机器学习算法(SVM、KNN、神经网络等)
- Min-Max标准化:适合数据有明确边界的情况(如图像像素值0-255)
- 稳健标准化:适合存在异常值的数据集
- 对数变换:适合偏态分布的数据
选择合适的标准化方法需要考虑数据的特点和后续算法的要求,如果不知道选择哪种方法,Z-Score标准化是最通用的选择。