数据预处理
1. 前言
数据质量分析是数据预处理的前提,也是数据挖掘分析结论有效性和准确性的基础。其主要任务是检查原始数据中是否存在脏数据。脏数据一般指的是不符合要求的,以及不能直接进行相应分析的数据。 常见的脏数据包括:
- 缺失值
- 异常值
本文介绍了 Python 数据分析中的数据预处理流程,涵盖数据质量分析、缺失值与异常值处理、数据集成与归约等关键步骤。通过描述性统计、箱线图、相关性分析及多种规范化方法,确保数据质量满足挖掘要求。内容包含具体代码示例与理论解释,适用于构建可靠的数据分析模型。

数据质量分析是数据预处理的前提,也是数据挖掘分析结论有效性和准确性的基础。其主要任务是检查原始数据中是否存在脏数据。脏数据一般指的是不符合要求的,以及不能直接进行相应分析的数据。 常见的脏数据包括:
在进行深入分析前,首先需要了解数据的整体分布情况。可以使用以下命令查看数据的基本情况:
data.describe() # 查看数据的基本情况
len(data) # 查看数据的总条数
通过描述性统计,可以快速识别数据中可能存在的空值或缺失模式。
检查数据中是否有录入错误以及含有不合理的数据。忽视这些异常值是十分危险的,可能会导致数据整体分析产生明显偏离观察值的影响。
通过一个简单的描述性估计,进而查看哪些数据是不合理的。需要的统计量可以是最大值和最小值,判断这个变量的极值是否不在现实合理范围之中。
import pandas as pd
# 读取数据,指定'日期'列为索引列
data = pd.read_excel('catering_sale.xls', index_col='日期')
data.describe() # 对数据进行描述性估计
输出结果通常包含 count, mean, std, min, 25%, 50%, 75%, max 等信息,帮助定位极端值。
如果数据服从正态分布,在 3σ 原则下,异常值被定义为一组测定值中与平均值的偏差超过三倍标准差的值。在正态分布的假设下,距离平均值 3σ 之外的值出现的概率小于 0.003,属于极个别的小概率事件。
箱形图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的鲁棒性:多达 25% 的数据可以变得任意远而不会很大地扰动四分位数,其结果比较客观,在识别异常值时有一定优越性。
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签--黑体
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure()
p = data.boxplot(return_type='dict') # 画箱线图,直接使用 DataFrame 的方法
# 获取异常值,'fliers'为箱线图中异常值的标签
x = p['fliers'][0].get_xdata()
y = p['fliers'][0].get_ydata()
y.sort() # 从小到大排序
for i in range(len(x)):
if i > 0:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i]+0.05 - 0.8/(y[i]-y[i-1]), y[i]))
else:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i]+0.08, y[i]))
plt.show()
数据不一致性是指数据的矛盾性、不相容性。直接对不一致的数据进行挖掘,可能会产生与实际相违背的挖掘结果。 在数据挖掘过程中,不一致数据的产生主要发生在数据集成的过程中,可能是由于被挖掘数据是来自于从不同的数据源、重复存放的数据未能进行一致性地更新造成的。例如两张表中都存储了用户的地址,在用户的地址发生改变时,如果只更新了一张表中的数据,那么这两张表中就有了不一致的数据。
绘制散点图矩阵并计算相关系数是分析变量间关系的重要手段。
import pandas as pd
D = pd.DataFrame([range(1, 8), range(2, 9)]) # 生成样本 D,一行为 1~7,一行为 2~8
print(D.corr(method='spearman')) # 计算相关系数矩阵
S1 = D.loc[0] # 提取第一行
S2 = D.loc[1] # 提取第二行
print(S1.corr(S2, method='pearson')) # 计算 S1、S2 的相关系数
import numpy as np
D = pd.DataFrame(np.random.randn(6, 5)) # 产生 6×5 随机矩阵
print(D.cov()) # 计算协方差矩阵
print(D[0].cov(D[1])) # 计算第一列和第二列的协方差
针对缺失值,常用的插补方法包括:
| 插补方法 | 描述 |
|---|---|
| 均值/中位数/众数插补 | 根据属性的类型,用该属性的这些特征进行插补 |
| 使用固定值 | 用一个常量替换 |
| 最近邻插补法 | 记录中找到与缺失样本最接近的该属性值插补 |
| 回归方法 | 根据已有数据与相关量建立拟合模型来预测属性值 |
| 插值法 | 利用已知点建立合适的插值函数,未知点由插值函数近似代替 |
以下是使用拉格朗日插值法处理缺失值的示例代码:
import pandas as pd
from scipy.interpolate import lagrange
inputfile = '../data/catering_sale.xls'
outputfile = '../tmp/sales.xls'
data = pd.read_excel(inputfile)
# 过滤异常值,将其变为空值以便演示插值
data['销量'][(data['销量'] < 400) | (data['销量'] > 5000)] = None
# 自定义列向量插值函数
# s 为列向量,n 为被插值的位置,k 为取前后的数据个数,默认为 5
def ployinterp_column(s, n, k=5):
y = s[list(range(n-k, n)) + list(range(n+1, n+1+k))] # 取数
y = y[y.notnull()] # 剔除空值
return lagrange(y.index, list(y))(n) # 插值并返回插值结果
# 逐个元素判断是否需要插值
for i in data.columns:
for j in range(len(data)):
if (data[i].isnull())[j]: # 如果为空即插值
data[i][j] = ployinterp_column(data[i], j)
data.to_excel(outputfile)
针对异常值,处理方法包括:
| 异常值处理方法 | 方法描述 |
|---|---|
| 删除含有异常值的记录 | 直接将异常值删除 |
| 视为缺失值 | 将异常值视为缺失值,利用缺失值处理方法进行处理 |
| 平均值修正 | 可以用前后两个观测值的平均值修正该异常值 |
| 不处理 | 直接在异常值数据集上进行挖掘建模 |
实体识别是统一不同源数据的矛盾之处,主要包括:
常见类型包括同一属性出现多次,或同一属性命名不一致导致重复。可以通过相关分析检测,根据两个数值型属性,根据其属性值,用相关系数度量一个属性在多大程度蕴含另一个属性。
对数据转换为'适当'形式,比如常见的函数变换,将数据进行简单压缩,将非平稳序列转换为平稳序列等等。
规范化旨在消除量纲影响,使不同指标具有可比性。
(data - data.min()) / (data.max() - data.min())
(data - data.mean()) / data.std()
data / 10 ** np.ceil(np.log10(data.abs().max()))
一些数据挖掘算法,特别是某些分类算法,如 ID3、Apriori 算法,要求数据是分类属性形式。离散化过程涉及确定分类数和如何将连续属性映射到这些分类值。
k = 4 # k 为划分区间数
d1 = pd.cut(data, k, labels=range(k)) # 等宽离散化
w = [1.0*i/k for i in range(k+1)]
w = data.describe(percentiles=w)[4:4+k+1]
w[0] = w[0]*(1-1e-10)
d2 = pd.cut(data, w, labels=range(k))
为了帮助用户获得更好的数据,需要利用抑制属性构造新的属性,并加入到现有的属性集中。这通常涉及领域知识的结合,例如从时间戳中提取星期几,或从经纬度计算距离等。
数据规约是将海量数据进行规约,规约之后的数据仍接近于保持原数据的完整性,但数据量小得多。
属性规约常用方法有:合并属性、逐步向前选择、逐步向后删除、决策树归纳、主成分分析。
| 属性归约 | 方法描述 |
|---|---|
| 合并属性 | 将一些旧属性合并为新属性 |
| 逐步向前选择 | 从一个空属性集开始,每次从原来属性选择一个当前最优的属性添加到属性子集中直到无法选出最优属性或满足一定阈值为止 |
| 逐步向后选择 | 类比于逐步向前选择,每次去除最差的属性 |
| 决策树归纳 | 利用决策树算法对初始数据进行分类归纳学习,生成一个初始决策树,没有出现的属性均视为无关属性 |
| PCA | 将许多相关性很高的变量转化为彼此相互独立或不相关变量 |
主成分分析(PCA)示例:
import numpy as np
from sklearn.decomposition import PCA
D = np.random.rand(10, 4)
pca = PCA() # n_components 默认为 4,代表选取几个特征向量
pca.fit(D)
print(pca.components_) # 返回模型的各个特征向量
数值归约主要通过减少数据量来降低计算成本,常用方法包括:
数据预处理是数据分析中最耗时但也最关键的一步。高质量的数据能够显著提升后续建模的效果。在实际项目中,应根据具体的业务场景和数据特点,灵活组合上述清洗、集成和归约策略。同时,注意保留数据处理的中间状态,以便于回溯和调试。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online