Python 数据分析预处理:Z-Score 标准化实战指南(附代码与应用场景)

Python 数据分析预处理:Z-Score 标准化实战指南(附代码与应用场景)

在数据分析与机器学习中,数据预处理是提升模型效果的关键步骤。Z-Score 标准化(又称标准差标准化)作为最常用的特征缩放方法之一,能将数据转换为均值为 0、标准差为 1 的标准正态分布,有效消除特征量纲差异带来的影响。本文将手把手教你用 Python 实现 Z-Score 标准化,结合原理讲解、代码演示、效果验证与实战应用,代码精简易上手,零基础也能快速掌握。

一、核心原理与应用场景

1. 核心原理

Z-Score 标准化的核心是将每个特征值减去该特征的均值,再除以该特征的标准差,公式如下:

\(z = \frac{x - \mu}{\sigma}\)

  • \(x\):原始特征值;
  • \(\mu\):该特征的均值;
  • \(\sigma\):该特征的标准差;
  • \(z\):标准化后的特征值(Z 分数)。

核心效果:标准化后的数据均值为 0、标准差为 1,所有特征处于同一量级,避免因量纲差异导致模型偏向某一特征(如 K-Means、SVM、线性回归等对特征尺度敏感的算法)。

2. 适用场景

  • 模型对特征尺度敏感时(如 K-Means、SVM、逻辑回归、神经网络等);
  • 特征间量纲差异较大时(如 “年龄(0-100)” 与 “收入(0-100000)”);
  • 需要保留特征分布趋势(如正态分布)时(区别于 Min-Max 归一化的 [0,1] 缩放)。

3. 不适用场景

  • 数据分布非正态时(可考虑 Min-Max 归一化或其他方法);
  • 需保留原始数据极值意义时(如电商订单金额的绝对大小)。

二、环境准备与数据集选择

1. 环境准备

工具 / 依赖

版本要求

作用描述

Python

3.7+

核心运行环境

pandas

1.0+

数据处理与加载

numpy

1.18+

数值计算(手动实现标准化)

scikit-learn

0.23+

快捷实现标准化(推荐)

matplotlib/seaborn

3.0+/0.10+

标准化效果可视化

pip

20.0+

Python 包管理工具

2. 依赖安装命令

打开终端执行以下命令,一键安装所需依赖:

pip install pandas numpyscikit-learn matplotlib seaborn

3. 数据集选择

选用 scikit-learn 内置的鸢尾花数据集(Iris),该数据集包含 4 个数值型特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度),特征量纲一致但数值范围不同,适合演示标准化效果:

# 加载数据集

from sklearn.datasets import load_iris

import pandas as pd

# 加载数据并转换为DataFrame

iris = load_iris()

X = iris.data # 特征矩阵(4个特征,150个样本)

feature_names = iris.feature_names # 特征名称

data = pd.DataFrame(X, columns=feature_names)

# 查看数据基本信息

print("标准化前数据预览:")

print(data.head())

print(f"\n数据集形状:{data.shape}") # 输出:(150, 4)

print("\n标准化前特征统计信息:")

print(data.describe().round(2)) # 保留2位小数

三、Python 实现 Z-Score 标准化(两种方法)

方法 1:手动实现(基于公式,理解原理)

通过 numpy 计算均值和标准差,手动套用 Z-Score 公式实现标准化,适合深入理解原理:

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

# 设置中文字体(避免中文乱码)

plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows系统

# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # Mac系统

plt.rcParams['axes.unicode_minus'] = False

def zscore_manual(data):

"""

手动实现Z-Score标准化

:param data: 输入数据(DataFrame或numpy数组)

:return: 标准化后的数据

"""

# 计算每个特征的均值和标准差

mean = np.mean(data, axis=0) # 按列计算均值

std = np.std(data, axis=0) # 按列计算标准差(ddof=0,总体标准差)

# 避免标准差为0导致除零错误

std = np.where(std == 0, 1e-8, std)

# 套用Z-Score公式

data_standardized = (data - mean) / std

return data_standardized, mean, std

# 执行手动标准化

data_manual_std, mean_manual, std_manual = zscore_manual(data.values)

data_manual_std_df = pd.DataFrame(data_manual_std, columns=feature_names)

# 查看标准化后结果

print("\n手动标准化后数据预览:")

print(data_manual_std_df.head().round(4))

print("\n手动标准化后特征统计信息(均值≈0,标准差≈1):")

print(data_manual_std_df.describe().round(4))

方法 2:Scikit-Learn 实现(推荐,高效快捷)

使用 scikit-learn 的StandardScaler类实现标准化,支持拟合 - 转换流程,便于后续模型复用(如训练集和测试集用同一套均值和标准差):

from sklearn.preprocessing import StandardScaler

def zscore_sklearn(data):

"""

用Scikit-Learn实现Z-Score标准化

:param data: 输入数据(DataFrame或numpy数组)

:return: 标准化后的数据、StandardScaler实例(含均值和标准差)

"""

scaler = StandardScaler() # 初始化标准化器

data_standardized = scaler.fit_transform(data) # 拟合+转换

return data_standardized, scaler

# 执行Sklearn标准化

data_sklearn_std, scaler = zscore_sklearn(data)

data_sklearn_std_df = pd.DataFrame(data_sklearn_std, columns=feature_names)

# 查看标准化后结果

print("\nSklearn标准化后数据预览:")

print(data_sklearn_std_df.head().round(4))

print("\nSklearn标准化后特征统计信息(均值≈0,标准差≈1):")

print(data_sklearn_std_df.describe().round(4))

# 查看Scikit-Learn计算的均值和标准差

print("\nScikit-Learn计算的特征均值:")

print(pd.Series(scaler.mean_, index=feature_names).round(4))

print("\nScikit-Learn计算的特征标准差:")

print(pd.Series(scaler.scale_, index=feature_names).round(4))

两种方法结果对比

# 验证两种方法结果一致性(误差在1e-10以内)

diff = np.abs(data_manual_std - data_sklearn_std).max()

print(f"\n两种方法结果最大误差:{diff:.10f}")

print("结论:两种方法结果一致,Scikit-Learn更高效且支持后续复用")

四、标准化效果可视化(直观验证)

通过直方图、箱线图对比标准化前后的数据分布变化,直观感受标准化效果:

1. 直方图对比(分布趋势保留)

# 创建子图(2行4列,对比4个特征)

fig, axes = plt.subplots(2, 4, figsize=(16, 8))

fig.suptitle('Z-Score标准化前后特征分布对比(直方图)', fontsize=16, fontweight='bold')

# 绘制标准化前直方图

for i, feature in enumerate(feature_names):

sns.histplot(data[feature], ax=axes[0, i], bins=15, color='#2E86AB', alpha=0.7)

axes[0, i].set_title(f'标准化前:{feature}', fontsize=11)

axes[0, i].set_xlabel('')

axes[0, i].grid(alpha=0.3)

# 绘制标准化后直方图

for i, feature in enumerate(feature_names):

sns.histplot(data_sklearn_std_df[feature], ax=axes[1, i], bins=15, color='#E74C3C', alpha=0.7)

axes[1, i].set_title(f'标准化后:{feature}', fontsize=11)

axes[1, i].set_xlabel('')

axes[1, i].grid(alpha=0.3)

plt.tight_layout()

plt.savefig('Z-Score标准化前后直方图对比.png', dpi=300)

plt.show()

2. 箱线图对比(尺度统一)

# 合并标准化前后数据,便于绘制箱线图

data_combined = pd.concat([

data.assign(类型='标准化前'),

data_sklearn_std_df.assign(类型='标准化后')

], ignore_index=True)

# 绘制箱线图

plt.figure(figsize=(14, 7))

sns.boxplot(x='变量', y='值', hue='类型',

data=pd.melt(data_combined, id_vars=['类型'], var_name='变量', value_name='值'),

palette=['#2E86AB', '#E74C3C'])

plt.title('Z-Score标准化前后特征箱线图对比(尺度统一)', fontsize=14, fontweight='bold')

plt.xlabel('特征名称', fontsize=12)

plt.ylabel('特征值', fontsize=12)

plt.grid(axis='y', alpha=0.3)

plt.legend(title='数据类型')

plt.tight_layout()

plt.savefig('Z-Score标准化前后箱线图对比.png', dpi=300)

plt.show()

可视化结果解读

  • 直方图:标准化后数据分布趋势与原始数据一致,但均值移至 0,标准差统一为 1;
  • 箱线图:标准化前各特征数值范围差异较大(如花瓣长度范围 1.0-6.9,花萼宽度范围 2.0-4.4),标准化后所有特征范围集中在 [-3, 3] 区间,尺度完全统一。

五、实战应用:标准化后的数据用于 K-Means 聚类

验证 Z-Score 标准化对聚类模型的影响(K-Means 对特征尺度敏感):

from sklearn.cluster import KMeans

# 1. 原始数据直接聚类

kmeans_raw = KMeans(n_clusters=3, random_state=42, n_init=10)

labels_raw = kmeans_raw.fit_predict(data)

# 2. 标准化后数据聚类

kmeans_std = KMeans(n_clusters=3, random_state=42, n_init=10)

labels_std = kmeans_std.fit_predict(data_sklearn_std)

# 3. 可视化聚类效果(用PCA降维到2D)

from sklearn.decomposition import PCA

# PCA降维

pca = PCA(n_components=2)

data_pca_raw = pca.fit_transform(data)

data_pca_std = pca.fit_transform(data_sklearn_std)

# 绘制聚类对比图

fig, axes = plt.subplots(1, 2, figsize=(16, 6))

fig.suptitle('Z-Score标准化对K-Means聚类效果的影响', fontsize=16, fontweight='bold')

# 原始数据聚类结果

sns.scatterplot(x=data_pca_raw[:, 0], y=data_pca_raw[:, 1], hue=labels_raw,

palette='viridis', s=60, alpha=0.8, ax=axes[0])

axes[0].set_title('原始数据聚类结果(尺度不一致)', fontsize=12)

axes[0].set_xlabel('PCA特征1', fontsize=11)

axes[0].set_ylabel('PCA特征2', fontsize=11)

axes[0].grid(alpha=0.3)

axes[0].legend(title='聚类编号')

# 标准化后数据聚类结果

sns.scatterplot(x=data_pca_std[:, 0], y=data_pca_std[:, 1], hue=labels_std,

palette='viridis', s=60, alpha=0.8, ax=axes[1])

axes[1].set_title('标准化后数据聚类结果(尺度统一)', fontsize=12)

axes[1].set_xlabel('PCA特征1', fontsize=11)

axes[1].set_ylabel('PCA特征2', fontsize=11)

axes[1].grid(alpha=0.3)

axes[1].legend(title='聚类编号')

plt.tight_layout()

plt.savefig('Z-Score标准化对K-Means聚类影响.png', dpi=300)

plt.show()

# 4. 定量评估聚类效果(轮廓系数)

from sklearn.metrics import silhouette_score

silhouette_raw = silhouette_score(data, labels_raw)

silhouette_std = silhouette_score(data_sklearn_std, labels_std)

print(f"\n原始数据聚类轮廓系数:{silhouette_raw:.4f}")

print(f"标准化后数据聚类轮廓系数:{silhouette_std:.4f}")

print("结论:标准化后聚类轮廓系数更高,聚类效果更优")

六、避坑指南(新手必看)

1. 训练集与测试集标准化一致性

  • 错误做法:分别对训练集和测试集拟合StandardScaler(导致两套均值 / 标准差,数据分布不一致);
  • 正确做法:用训练集拟合StandardScaler,再用同一实例转换测试集:

# 示例:训练集与测试集拆分后的标准化

from sklearn.model_selection import train_test_split

# 拆分训练集(80%)和测试集(20%)

X_train, X_test = train_test_split(data, test_size=0.2, random_state=42)

# 正确做法:用训练集拟合,同时转换训练集和测试集

scaler = StandardScaler()

X_train_std = scaler.fit_transform(X_train) # 训练集:拟合+转换

X_test_std = scaler.transform(X_test) # 测试集:仅转换(复用训练集的均值/标准差)

print("训练集标准化后均值:", np.mean(X_train_std, axis=0).round(4))

print("测试集标准化后均值:", np.mean(X_test_std, axis=0).round(4)) # 接近0但非严格0,正常现象

2. 处理标准差为 0 的特征

  • 问题:若某特征所有值相同(标准差为 0),标准化时会出现除零错误;
  • 解决方法:提前删除这类无区分度的特征,或用极小值(如 1e-8)替代 0 标准差:

# 检查标准差为0的特征

std_zero_features = data.columns[data.std(axis=0) < 1e-8]

if len(std_zero_features) > 0:

print(f"需删除的无区分度特征:{list(std_zero_features)}")

data = data.drop(columns=std_zero_features) # 删除特征

3. 数据分布对标准化的影响

  • 问题:若数据非正态分布,Z-Score 标准化后可能无法达到理想效果;
  • 解决方法:先对数据做正态转换(如对数转换、Box-Cox 转换),再进行标准化。

4. 中文乱码问题

  • 错误现象:图表中中文显示为问号;
  • 解决方法:正确设置中文字体(Windows 用SimHei,Mac 用Arial Unicode MS)。

七、进阶扩展(按需优化)

1. 批量处理 CSV 文件数据

# 读取CSV文件并标准化

def zscore_csv(input_path, output_path):

"""

读取CSV文件,对数值型特征进行Z-Score标准化,保存结果

:param input_path: 输入CSV文件路径

:param output_path: 输出CSV文件路径

"""

# 读取数据

data = pd.read_csv(input_path)

# 筛选数值型特征

numeric_features = data.select_dtypes(include=[np.number]).columns

# 标准化数值型特征

scaler = StandardScaler()

data[numeric_features] = scaler.fit_transform(data[numeric_features])

# 保存结果

data.to_csv(output_path, index=False, encoding='utf-8-sig')

print(f"标准化完成,结果保存至:{output_path}")

return scaler

# 调用函数(替换为实际文件路径)

# scaler = zscore_csv('原始数据.csv', '标准化后数据.csv')

2. 结合 Pipeline 实现端到端流程

# 用Pipeline将标准化与模型训练串联(避免数据泄露)

from sklearn.pipeline import Pipeline

from sklearn.linear_model import LogisticRegression

from sklearn.metrics import accuracy_score

# 准备分类任务数据(鸢尾花数据集标签)

y = iris.target

# 拆分训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(data, y, test_size=0.2, random_state=42)

# 构建Pipeline(标准化+逻辑回归)

pipeline = Pipeline([

('zscore', StandardScaler()), # 第一步:标准化

('classifier', LogisticRegression(random_state=42)) # 第二步:分类模型

])

# 训练模型(自动先对训练集标准化,再训练)

pipeline.fit(X_train, y_train)

# 预测(自动对测试集标准化,再预测)

y_pred = pipeline.predict(X_test)

# 评估效果

accuracy = accuracy_score(y_test, y_pred)

print(f"\nPipeline端到端流程准确率:{accuracy:.4f}")

总结

本文通过 “原理讲解 + 两种实现方法 + 效果可视化 + 实战应用” 的方式,手把手教你掌握 Python 中 Z-Score 标准化的核心技巧,核心亮点如下:

  1. 原理清晰:用公式 + 实例解释 Z-Score 标准化本质,让新手理解 “为何标准化”;
  2. 代码精简:提供手动实现(理解原理)和 Scikit-Learn 实现(实战推荐),兼顾深度与效率;
  3. 效果直观:通过直方图、箱线图、聚类对比,可视化验证标准化价值;
  4. 实用性强:覆盖避坑指南、批量处理、Pipeline 集成等实战场景,直接复用。

Z-Score 标准化是数据分析与机器学习的基础预处理步骤,尤其适合对特征尺度敏感的模型。按照本文步骤操作,即可轻松实现数据标准化,为后续建模提供高质量数据支撑。

Read more

【算法通关指南:算法基础篇】二分算法:1.在排序树组中查找元素的第一个和最后一个位置 2.牛可乐和魔法封印

【算法通关指南:算法基础篇】二分算法:1.在排序树组中查找元素的第一个和最后一个位置 2.牛可乐和魔法封印

🔥小龙报:个人主页 🎬作者简介:C++研发,嵌入式,机器人方向学习者 ❄️个人专栏:《算法通关指南》 ✨ 永远相信美好的事情即将发生 文章目录 * 前言 * 一、二分算法 * 二、在排序树组中查找元素的第一个和最后一个位置 * 2.1题目 * 2.2 算法原理 * 2.3代码 * 三、牛可乐和魔法封印 * 3.1题目 * 3.2 算法原理 * 3.3代码 * 总结与每日励志 前言 本专栏聚焦算法题实战,系统讲解算法模块:以《c++编程》,《数据结构和算法》《基础算法》《算法实战》 等几个板块以题带点,讲解思路与代码实现,帮助大家快速提升代码能力ps:本章节题目分两部分,比较基础笔者只附上代码供大家参考,其他的笔者会附上自己的思考和讲解,希望和大家一起努力见证自己的算法成长 一、

By Ne0inhk
数据结构【栈和队列附顺序表应用算法】

数据结构【栈和队列附顺序表应用算法】

栈和队列和顺序表应用算法练习 * 1.栈 * 1.1概念与结构 * 1.2栈的实现 * 2.队列 * 2.1概念与结构 * 2.2队列的实现 * 3.附(顺序表应用算法) * 3.1移除元素 * 3.2删除有序数组中的重复项 * 3.3合并两个有序数组 1.栈 1.1概念与结构 栈:⼀种特殊的线性表,其只允许在固定的⼀端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另⼀端称为栈底。栈中的数据元素遵守后进先出的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈,出数据也在栈顶。 1.2栈的实现 typedefint STDataType;typedefstructStack{ STDataType * a;int

By Ne0inhk
【笔试】算法的暴力美学——牛客 NC221681:dd爱框框

【笔试】算法的暴力美学——牛客 NC221681:dd爱框框

一、题目描述 二、算法原理 思路:滑动窗口 1)定义两个指针,一开始都为0,cur 从左开始遍历,定义一个 sum 来表示 prev 到 cur 的之间的值的总和,当 sum >= x 时,我们要根据题目条件来保存 prev 和 cur 的值; 2)当 sum >= x 时,我们记录完 prev 和 cur 的值的之后,sum -= arr[ prev ],prev++ ,往后走,只要满足条件 sum >= x 我们就要记录

By Ne0inhk
python基于大数据的手机商品数据分析

python基于大数据的手机商品数据分析

目录 * 手机商品数据分析的摘要 * 开发技术路线 * 相关技术介绍 * 核心代码参考示例 * 结论 * 源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 手机商品数据分析的摘要 随着智能手机市场的快速发展,海量数据为产品优化和商业决策提供了重要依据。Python凭借其强大的数据处理和可视化能力,成为手机商品数据分析的核心工具。 数据采集阶段,可通过爬虫技术(如Scrapy、BeautifulSoup)从电商平台(京东、淘宝)获取手机销售数据,包括价格、销量、用户评价等。结构化数据存储于MySQL或MongoDB,非结构化数据(如评论文本)通过NLTK或jieba进行分词和情感分析。 数据清洗环节使用Pandas处理缺失值和异常值,例如剔除价格异常记录或填充平均评分。特征工程中,提取关键指标如品牌市场份额、价格分布、用户满意度,并利用Matplotlib或Seaborn生成可视化图表(如热力图展示品牌-价格相关性)。 机器学习模型(如随机森林、XGBoost)可预测销量趋势或用户购买意愿,特征重要性分析揭示影响销量的核心因素(如CP

By Ne0inhk