Python数据标准化归一化方法教程
用pandas和sklearn做Min-Max归一化、Z-score标准化,解决不同量纲字段(金额与数量)在模型、相似度计算中权重失衡的问题。
场景痛点
做客户分群、相似推荐、回归预测时,金额列动辄几万、数量列只有个位数,不标准化的话金额会主导计算结果。Excel里手动算 (x-min)/(max-min) 每列拖一遍,几十列就疯了。用pandas一行公式或sklearn的Scaler,几行搞定。
用到的库
pip install pandas scikit-learn
完整代码
import pandas as pd
from sklearn.preprocessing import MinMaxScaler, StandardScaler
def sample_df():
return pd.DataFrame({
"amount": [1000, 5000, 10000, 20000, 3000],
"qty": [1, 3, 5, 10, 2],
"credit": [600, 650, 700, 800, 620],
})
def norm_demo():
df = sample_df()
print("原始:")
print(df)
# 1. Min-Max归一化:缩放到 [0,1],用pandas手写
df["amount_minmax"] = (df["amount"] - df["amount"].min()) / (df["amount"].max() - df["amount"].min())
# 2. 用sklearn批量归一化多列
scaler = MinMaxScaler()
scaled = scaler.fit_transform(df[["amount", "qty", "credit"]])
df_scaled = pd.DataFrame(scaled, columns=["amount_m", "qty_m", "credit_m"])
print("\nMin-Max归一化后:")
print(df_scaled.round(3))
# 3. Z-score标准化:均值0,标准差1
std_scaler = StandardScaler()
std_arr = std_scaler.fit_transform(df[["amount", "qty", "credit"]])
df_std = pd.DataFrame(std_arr, columns=["amount_z", "qty_z", "credit_z"])
print("\nZ-score标准化后:")
print(df_std.round(3))
# 4. 反归一化:把模型结果还原回原始量纲
back = scaler.inverse_transform(df_scaled)
print("\n反归一化还原:")
print(pd.DataFrame(back, columns=["amount", "qty", "credit"]).round(2))
if __name__ == "__main__":
norm_demo()
代码讲解
- Min-Max归一化公式:
(x - min) / (max - min),结果落在[0,1]。适合数据分布比较集中、没有极端异常值的场景。 - Z-score标准化公式:
(x - mean) / std,结果均值为0标准差为1。适合近似正态分布、有异常值的场景。 MinMaxScaler().fit_transform(df[cols])一次性对多列拟合并转换,返回numpy数组,再转成DataFrame。scaler.inverse_transform把标准化后的数据还原回原始量纲,模型预测完要还原成业务金额时用。- 同一批scaler要保存下来,新数据预测时用同一个scaler转换,不能每次重新fit。
运行结果
控制台打印原始DataFrame、Min-Max归一化后三列都在0到1之间、Z-score标准化后均值约0、以及反归一化还原后的原始数值。归一化后amount和qty量纲拉齐,可以直接做距离计算或模型输入。
注意事项
- 归一化对异常值敏感,先做异常值处理再归一化,见 异常值检测。
- 训练集fit、测试集transform:把scaler从训练集学的min/max套用到测试集,别在测试集上重新fit,否则数据泄露。
- 稀疏计数列(如点击次数)适合用
MaxAbsScaler,不会把零变成负数。 - 业务报表展示不要做归一化,原始金额才是业务语言;标准化只用于模型或距离计算。

更新时间:2026-09-14 21:01:40