数据预处理学习笔记
一、缺失值处理
1. 缺失值识别(Pandas)
核心问题:原始数据中缺失值可能以NaN、n/a、na、-等不同形式存在,需先统一识别。
关键函数:isnull()
作用:判断数据框(DataFrame)中每个单元格是否为空,返回布尔值(True为空,False为非空)。
示例代码:
import pandas as pd
# 定义需识别的缺失值形式
missing_values = ["n/a", "na", "-"]
df = pd.read_csv('property-data.csv', na_values=missing_values)
# 查看某列缺失值情况
print(df['NUM_BEDROOMS'].isnull())
2. 缺失值处理方法(Pandas)
(1)删除缺失值:dropna()
作用:删除包含空字段的行或列(默认删行),适用于缺失值占比极低的场景。
关键参数:
参数 含义与取值
axis 0(默认):删行;1:删列
how any(默认):有一个空值就删;all:所有值为空才删
subset 指定需检查的列(如subset=['NUM_BEDROOMS', 'SQ_FT'])
inplace True:直接修改原数据;False:返回新数据(默认)
示例代码:
new_df = df.dropna(how='any', subset=['NUM_BEDROOMS']) # 删去NUM_BEDROOMS列有空值的行
(2)填充缺失值:fillna()
作用:用指定值或统计量替换空字段,避免数据丢失,适用场景更广。
常见填充方式:
固定值填充:用自定义常数(如666)填充。
示例:df.fillna(666, inplace=True)
均值填充:用该列非空值的均值填充(适用于连续型数据,受极端值影响较大)。
示例:
x = df["ST_NUM"].mean() # 计算ST_NUM列均值
df["ST_NUM"].fillna(x, inplace=True)
中位数填充:用该列非空值的中位数填充(适用于连续型数据,抗极端值能力强)。
示例:
x = df["ST_NUM"].median() # 计算ST_NUM列中位数
df["ST_NUM"].fillna(x, inplace=True)
3. 缺失值处理方法(Scikit-learn)
核心类:Impute.SimpleImputer()
作用:标准化处理缺失值,支持多种填充策略,适用于机器学习流水线(Pipeline)。
常见策略:
策略(strategy) 适用场景 示例代码
mean(默认) 连续型数据 imp_mean = SimpleImputer(missing_values=np.nan, strategy="mean")
median 连续型数据(抗极端值) imp_median = SimpleImputer(strategy="median")
constant 自定义固定值 imp_0 = SimpleImputer(strategy="constant", fill_value=0)
most_frequent(众数) 分类型数据(如性别、Embarked港口) imp_mode = SimpleImputer(strategy="most_frequent")
示例(众数填充分类特征):
from sklearn.impute import SimpleImputer
# 处理Embarked(港口)特征的缺失值
Embarked = data.loc[:, "Embarked"].values.reshape(-1, 1)
imp_mode = SimpleImputer(strategy="most_frequent")
data.loc[:, "Embarked"] = imp_mode.fit_transform(Embarked)
二、数据标准化
1. 核心概念与目的
定义:将数据“无量纲化”,即把不同规格、不同分布的特征调整到统一标准,消除量纲影响(如“身高(cm)”和“体重(kg)”的单位差异)。
核心目的:避免方差过大的特征主导模型训练,让所有特征对模型的影响更均衡。
常见类型:线性无量纲化(包括中心化、缩放),目标通常是将数据转换为“均值为0、方差为1”的标准正态分布。
2. 常用标准化方法(Scikit-learn)
(1)最大最小值标准化:preprocessing.MinMaxScaler()
原理:将数据缩放到指定范围(默认[0,1]),公式为:
x_{scaled} = \frac{x - x_{min}}{x_{max} - x_{min}}
(x_{min}为特征最小值,x_{max}为特征最大值)
关键参数:feature_range:指定缩放范围(如[5,10])。
示例代码:
from sklearn.preprocessing import MinMaxScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler(feature_range=[5, 10]) # 缩放到5-10
result = scaler.fit_transform(data) # 输出:[[5.,5.], [6.25,6.25], [7.5,7.5], [10.,10.]]
(2)Z值标准化:preprocessing.StandardScaler()
原理:将数据转换为标准正态分布(均值=0,方差=1),公式为:
x_{scaled} = \frac{x - \mu}{\sigma}
(\mu为特征均值,\sigma为特征标准差)
优势:保留数据原始分布关系,对异常值更鲁棒。
示例代码:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_std = scaler.fit_transform(data)
print(x_std.mean()) # 输出≈0.0
print(x_std.std()) # 输出≈1.0
三、特征编码
1. 特征类型划分
需根据特征的性质选择编码方式,常见类型:
名义变量:无顺序关系的分类特征(如性别:男/女、血型:A/B/AB/O)。
有序变量:有顺序但不可计算的分类特征(如学历:小学<初中<高中)。
有距变量:有数值意义且可计算的连续/离散特征(如分数:100/90/60)。
2. 常用编码方法(Scikit-learn)
(1)独热编码:preprocessing.OneHotEncoder()
适用场景:名义变量(无顺序的分类特征),避免模型误解特征的“数值大小关系”。
原理:对有N个取值的特征,编码为N维稀疏向量(仅对应取值的位置为1,其余为0)。
示例:血型(A/B/AB/O)→ A:(1,0,0,0)、B:(0,1,0,0)、AB:(0,0,1,0)、O:(0,0,0,1)。
(2)序号编码:preprocessing.OrdinalEncoder()
适用场景:有序变量(有顺序的分类特征),保留特征的顺序关系。
原理:将分类取值按顺序映射为整数(如学历:小学→1、初中→2、高中→3)。
注意:仅用于输入特征(X),不用于目标标签(y)。
(3)目标标签编码:preprocessing.LabelEncoder()
适用场景:目标标签(y)的编码(如“ Survived:Yes/No”→1/0),无顺序要求。
原理:将标签映射为0到n_{classes}-1的整数(n_{classes}为标签类别数)。
注意:仅用于目标变量(y),不可用于输入特征(X),否则会引入无意义的数值关系。
四、数据二值化
1. 核心概念
定义:根据“阈值(threshold)”将连续型数据分为两类(0或1),大于阈值为1,小于等于阈值为0。
适用场景:需将连续特征简化为“是/否”逻辑的场景(如年龄:>30→1,≤30→0)。
2. 实现方法(Scikit-learn)
核心类:preprocessing.Binarizer()
示例代码:
from sklearn.preprocessing import Binarizer
# 将年龄二值化(阈值=30)
X = data_2.iloc[:, 0].values.reshape(-1, 1) # 年龄列(连续数据)
transformer = Binarizer(threshold=30).fit_transform(X) # 二值化
data_2.iloc[:, 0] = transformer # 替换原年龄列