数据清洗(缺失值处理、异常值处理、数据标准化)
文章目录
在数据处理与分析流程中,数据清洗占据着极为关键的地位。原始数据往往充斥着各种问题,如缺失值、异常值,且数据的尺度和分布也可能存在差异,这些问题会严重影响后续数据分析和机器学习模型的准确性与性能。因此,有效的数据清洗操作必不可少,它能够提升数据质量,为挖掘数据价值奠定坚实基础。接下来,我们将深入探讨数据清洗中的缺失值处理、异常值处理以及数据标准化这三个重要方面。
缺失值处理
1.1 缺失值的识别
在Python中,利用pandas库能够便捷地识别数据中的缺失值。对于一个存储数据的DataFrame对象,通过isnull()
方法可生成一个与原数据结构相同的布尔值DataFrame,其中True代表对应位置的数据缺失,False表示数据存在。例如:
import pandas as pd
data = pd.read_csv('your_data.csv')
missing_values = data.isnull()
print(missing_values.head())
若要统计每列的缺失值数量,可使用sum()
方法:
missing_count = data.isnull().sum()
print(missing_count)
1.2 缺失值处理方法
删除法
当缺失值在数据中所占比例较小,且删除含缺失值的样本不会对整体数据的代表性造成显著影响时,可采用删除法。删除行数据可使用dropna()
方法,默认情况下,只要某行存在缺失值,该行就会被删除:
cleaned_data = data.dropna()
若只想删除那些所有值都缺失的行,可设置how='all'
参数:
cleaned_data = data.dropna(how='all')
删除列数据时,需指定axis = 1
参数。例如,删除所有缺失值超过一定比例(如50%)的列:
threshold = len(data) * 0.5
cleaned_data = data.dropna(axis = 1, thresh = threshold)
填充法
填充法是用特定的值替代缺失值。常用的填充值包括常数、均值、中位数、众数等。使用pandas的fillna()
方法可实现填充操作。
- 常数填充:
使用一个固定的常数来填充所有缺失值,这种方法适用于数据缺失原因较为简单且该常数具有一定实际意义的情况。例如,在表示温度的数据中,如果存在少量缺失值,且根据实际情况,这些缺失值可能表示温度未测量,可将其填充为一个特殊值,如-999来表示数据缺失状态。代码示例如下:
cleaned_data = data.fillna(-999)
- 均值填充:
计算数据列的均值,并使用均值来填充缺失值。这种方法基于数据的整体平均水平进行填充,适用于数据分布较为均匀,且缺失值不会对均值产生较大影响的情况。例如,对于学生考试成绩数据列,可通过计算所有学生成绩的均值来填充缺失成绩:
mean_values = data.mean()
cleaned_data = data.fillna(mean_values)
- 中位数填充:
中位数是将数据排序后位于中间位置的值(如果数据个数为奇数)或中间两个值的平均值(如果数据个数为偶数)。相比于均值,中位数对异常值不敏感。当数据中存在异常值,且这些异常值可能影响均值的代表性时,使用中位数填充更为合适。例如,在员工薪资数据中,可能存在少数高收入的管理层员工拉高了整体均值,此时使用中位数填充缺失薪资更能反映一般员工的薪资水平:
median_values = data.median()
cleaned_data = data.fillna(median_values)
- 众数填充:
众数是数据集中出现频率最高的值。当数据具有明显的集中趋势,且缺失值的分布与多数数据相似时,众数填充是一种有效的方法。例如,在一个调查人们最喜欢的颜色的数据集中,若存在缺失值,可使用出现次数最多的颜色来填充缺失值:
mode_values = data.mode().iloc[0]
cleaned_data = data.fillna(mode_values)
此外,对于时间序列数据,还可使用前向填充(ffill
)或后向填充(bfill
)方法,即使用前一个或后一个非缺失值来填充当前缺失值:
cleaned_data = data.fillna(method='ffill')
插值法
插值法是根据已有数据的趋势来估计缺失值。scipy.interpolate
库提供了多种插值方法,如线性插值。假设我们有一个包含时间序列数据的DataFrame,索引为时间:
from scipy.interpolate import interp1d
import numpy as np
# 提取时间和数据列
time = data.index.values
values = data['your_column'].values
# 去除缺失值对应的时间和数据
valid_time = time[~np.isnan(values)]
valid_values = values[~np.isnan(values)]
# 创建线性插值函数
f = interp1d(valid_time, valid_values, kind='linear')
# 对缺失值进行插值
data['your_column'] = f(time)
异常值处理
2.1 异常值的检测
基于统计方法
- 箱线图法:箱线图能够直观展示数据的分布情况。在箱线图中,数据被划分为四分位数(Q1、Q2、Q3),四分位距(IQR = Q3 - Q1)。通常,将位于Q1 - 1.5 * IQR以下或Q3 + 1.5 * IQR以上的数据点视为异常值。利用pandas和matplotlib可绘制箱线图并识别异常值:
import matplotlib.pyplot as plt
import pandas as pd
data = pd.read_csv('your_data.csv')
data['your_column'].plot(kind='box')
plt.show()
Q1 = data['your_column'].quantile(0.25)
Q3 = data['your_column'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = data[(data['your_column'] < lower_bound) | (data['your_column'] > upper_bound)]
print(outliers)
- Z - 分数法:Z - 分数表示数据点与均值的偏离程度,计算公式为 Z = x − μ σ Z = \frac{x - \mu}{\sigma} Z=σ