Pandas 机器学习数据预处理:从缺失值到特征切分的全面解析
本文详细介绍了使用Pandas进行机器学习数据预处理的常用技巧,涵盖了数据清洗、异常值处理、训练与测试集划分等步骤。首先,我们展示了如何处理缺失数据,使用dropna()
删除缺失值,并用图表直观展示异常值的处理过程。接着,讲解了如何将数据集划分为训练集和测试集,介绍了按顺序和随机打乱两种划分方式。通过自定义函数,我们进一步展示了如何将数据切分为特征和标签,并将其转换为NumPy数组,以便于机器学习模型的应用。整篇文章通过丰富的代码示例,帮助读者掌握数据预处理的基本流程,为后续的建模和分析工作打下坚实基础。
文章目录
- [Pandas 机器学习数据预处理:从缺失值到特征切分的全面解析](#Pandas 机器学习数据预处理:从缺失值到特征切分的全面解析)
预备课:
pandas 异常数据处理:NaN 检查、填充与范围裁剪方法
Pandas 文件读取与保存指南:高效处理 CSV、Excel 等多种格式数据
Python Numpy 的 View 与 Copy 使用详解与优化技巧
导入第三方包
python
import pandas as pd
import matplotlib.pyplot as plt
一 读取数据
在源码包中 pandas > data > iris.csv
中查找或者 下载莺尾花数据。
python
columns = ["sepal length", "sepal width", "petal length", "petal width", "class"]
df = pd.read_csv("data/iris.csv", names=columns)
print(df)
二 处理NaN数据
python
print(df.isna())
print(df.isna().any())
print(df.loc[pd.isna(df["petal width"])])
df1 = df.dropna(axis=0, how="any")
print(df1)
print(df1.isna().any())
df.dropna(axis=0, how="any")
用于删除包含缺失值的行。axis=0
表示按行删除,how="any"
表示只要行中有一个缺失值(NaN)就删除该行。
三 异常值处理
用可视化画图的方式可以高效的看出异常值。
1)查看全部数据
python
df1 = df.dropna(axis=0, how="any")
df1.plot()
plt.show()
2)查看单列数据
单列数据画图排查异常
python
df1["sepal length"].plot()
plt.show()
3)删除异常数据
删除异常数据
python
index = df1[df1["sepal length"] < 0].index
df2 = df1.drop(index)
df2["sepal length"].plot()
plt.show()
4)查看数据分布
查看数据分布
python
df2["sepal length"].hist(bins=20)
plt.show()
四 切分训练和测试数据
将一份数据切分为 20% 测试数据 和 80% 训练数据。
python
# 获取 df2 数据的总行数
total_data = len(df2)
# 第一次划分
# 计算 80% 数据作为训练集的大小
n_train = int(total_data * 0.8)
# 按照顺序划分前 80% 的数据作为训练集
train_data = df2.iloc[:n_train]
print(train_data) # 打印训练集数据
# 剩余的 20% 数据作为测试集
test_data = df2.iloc[n_train:]
print(test_data) # 打印测试集数据
# 第二次划分
# 使用 sample() 方法随机打乱数据集
df3 = df2.sample(frac=1) # frac=1 表示打乱整个数据集
print(df3) # 打印打乱后的数据
# 从打乱后的数据中再次划分前 80% 为训练集
train_data = df3.iloc[:n_train]
print(train_data) # 打印重新划分后的训练集数据
# 剩余的 20% 数据作为测试集
test_data = df3.iloc[n_train:]
print(test_data) # 打印重新划分后的测试集数据
代码释义
-
计算数据总量 :
total_data = len(df2)
获取df2
数据集的总行数。 -
划分训练集和测试集:
n_train = int(total_data * 0.8)
计算出 80% 数据的大小,作为训练集的大小。train_data = df2.iloc[:n_train]
通过iloc
获取前 80% 数据作为训练集。test_data = df2.iloc[n_train:]
获取剩余的 20% 数据作为测试集。
-
打乱数据:
df3 = df2.sample(frac=1)
使用sample()
方法打乱df2
中的所有行,frac=1
表示打乱整个 DataFrame。- 你可以通过
print(df3)
打印出打乱后的数据。
-
重新划分训练集和测试集:
-
打乱后的数据被存储在
df3
中。然后,你再次按照 80% 和 20% 的比例划分训练集和测试集:
train_data = df3.iloc[:n_train]
获取前 80% 为训练集。test_data = df3.iloc[n_train:]
获取剩余的 20% 为测试集。
-
在第二次划分时确保数据是经过随机打乱的,以避免某种顺序上的偏差。
五 切分标签数据
- 数据切分 :通过
get_xy()
函数将训练和测试数据集切分为特征(train_x
,test_x
)和标签(train_y
,test_y
)。 - 数据转换 :将 Pandas DataFrame 或 Series 转换为 NumPy 数组,以便于后续的机器学习模型使用。为什么要转换为 NumPy 数组?请看 Python Numpy 的 View 与 Copy 使用详解与优化技巧。
- 数据检查 :使用
head()
打印数据集的前5行,以便检查数据是否正确切分和处理。
python
def get_xy(df):
return df[["sepal length", "sepal width", "petal length", "petal width"]], df[["class"]]
# 切分标签数据
# 输出训练数据集(train_data)中 "class" 列的所有值,假设 "class" 列为标签列
print()
print(train_data.loc[:, "class"])
# 使用自定义函数 get_xy() 将训练数据集切分为特征数据(train_x)和标签数据(train_y)
train_x, train_y = get_xy(train_data)
# 输出训练集特征数据(train_x)的前 5 行
print(train_x.head())
# 输出训练集标签数据(train_y)的前 5 行
print(train_y.head())
# 使用自定义函数 get_xy() 将测试数据集切分为特征数据(test_x)和标签数据(test_y)
test_x, test_y = get_xy(test_data)
# 输出测试集特征数据(test_x)的前 5 行
print(test_x.head())
# 输出测试集标签数据(test_y)的前 5 行
print(test_y.head())
# 将训练集特征数据(train_x)和标签数据(train_y)转换为 NumPy 数组
train_x_array, train_y_array = train_x.values, train_y.values
# 输出训练集特征数据(train_x_array)的前 3 行
print(train_x_array[:3])
# 输出训练集标签数据(train_y_array)的前 3 行
print(train_y_array[:3])
代码释义
train_data.loc[:, "class"]
:loc
用于选择指定列,这里选择了train_data
数据集中的"class"
列。:
表示选择所有行,"class"
是列标签。- 目的是输出训练数据集中所有样本的标签数据。
get_xy(train_data)
:get_xy()
是一个假设的函数,用来从传入的数据集中分离特征数据(train_x
)和标签数据(train_y
)。- 假设
train_x
包含特征数据(例如数值数据),train_y
包含标签数据(通常是分类标签)。
print(train_x.head())
和print(train_y.head())
:- 这两行代码打印出
train_x
和train_y
的前 5 行,帮助查看数据是否正确切分。
- 这两行代码打印出
test_x, test_y = get_xy(test_data)
:- 与训练数据集相同,这行代码将测试数据集
test_data
切分为特征数据(test_x
)和标签数据(test_y
)。
- 与训练数据集相同,这行代码将测试数据集
train_x_array, train_y_array = train_x.values, train_y.values
:train_x.values
和train_y.values
将 Pandas DataFrame 或 Series 转换为 NumPy 数组,因为许多机器学习框架(如 scikit-learn)要求输入数据为 NumPy 数组格式。train_x_array
和train_y_array
存储了训练集的特征数据和标签数据。
print(train_x_array[:3])
和print(train_y_array[:3])
:- 这两行代码分别打印出训练集特征数据和标签数据的前 3 行,以便验证数据是否正确转换为 NumPy 数组。
六 完整代码示例
python
# This is a sample Python script.
# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import pandas as pd
import matplotlib.pyplot as plt
def get_xy(df):
return df[["sepal length", "sepal width", "petal length", "petal width"]], df[["class"]]
def print_hi(name):
# Use a breakpoint in the code line below to debug your script.
print(f'Hi, {name}') # Press ⌘F8 to toggle the breakpoint.
# 加载数据
columns = ["sepal length", "sepal width", "petal length", "petal width", "class"]
df = pd.read_csv("data/iris.csv", names=columns)
print(df)
# NaN数据处理
print(df.isna())
print(df.isna().any())
print(df.loc[pd.isna(df["petal width"])])
df1 = df.dropna(axis=0, how="any")
print(df1)
print(df1.isna().any())
# 异常值处理
df1.plot()
plt.show()
df1["sepal length"].plot()
plt.show()
index = df1[df1["sepal length"] < 0].index
df2 = df1.drop(index)
df2["sepal length"].plot()
plt.show()
df2["sepal length"].hist(bins=20)
plt.show()
# 切分训练和测试数据
total_data = len(df2)
n_train = int(total_data * 0.8)
train_data = df2.iloc[:n_train]
print(train_data)
test_data = df2.iloc[n_train:]
print(test_data)
df3 = df2.sample(frac=1)
print(df3)
train_data = df3.iloc[:n_train]
print(train_data)
test_data = df3.iloc[n_train:]
print(test_data)
# 切分标签数据
print(train_data.loc[:, "class"])
train_x, train_y = get_xy(train_data)
print(train_x.head())
print(train_y.head())
test_x, test_y = get_xy(test_data)
print(test_x.head())
print(test_y.head())
train_x_array, train_y_array = train_x.values, train_y.values
print(train_x_array[:3])
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print_hi('机器学习数据预处理')
# See PyCharm help at https://www.jetbrains.com/help/pycharm/
复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。
lua
Hi, 机器学习数据预处理
sepal length sepal width petal length petal width class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
.. ... ... ... ... ...
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica
[150 rows x 5 columns]
sepal length sepal width petal length petal width class
0 False False False False False
1 False False False False False
2 False False False False False
3 False False False False False
4 False False False False False
.. ... ... ... ... ...
145 False False False False False
146 False False False False False
147 False False False False False
148 False False False False False
149 False False False False False
[150 rows x 5 columns]
sepal length False
sepal width False
petal length False
petal width True
class False
dtype: bool
sepal length sepal width petal length petal width class
25 5.0 3.0 1.6 NaN Iris-setosa
sepal length sepal width petal length petal width class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
.. ... ... ... ... ...
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica
[149 rows x 5 columns]
sepal length False
sepal width False
petal length False
petal width False
class False
dtype: bool
sepal length sepal width petal length petal width class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
.. ... ... ... ... ...
115 6.4 3.2 5.3 2.3 Iris-virginica
116 6.5 3.0 5.5 1.8 Iris-virginica
117 7.7 3.8 6.7 2.2 Iris-virginica
118 7.7 2.6 6.9 2.3 Iris-virginica
119 6.0 2.2 5.0 1.5 Iris-virginica
[118 rows x 5 columns]
sepal length sepal width petal length petal width class
120 6.9 3.2 5.7 2.3 Iris-virginica
121 5.6 2.8 4.9 2.0 Iris-virginica
122 7.7 2.8 6.7 2.0 Iris-virginica
123 6.3 2.7 4.9 1.8 Iris-virginica
124 6.7 3.3 5.7 2.1 Iris-virginica
125 7.2 3.2 6.0 1.8 Iris-virginica
126 6.2 2.8 4.8 1.8 Iris-virginica
127 6.1 3.0 4.9 1.8 Iris-virginica
128 6.4 2.8 5.6 2.1 Iris-virginica
129 7.2 3.0 5.8 1.6 Iris-virginica
130 7.4 2.8 6.1 1.9 Iris-virginica
131 7.9 3.8 6.4 2.0 Iris-virginica
132 6.4 2.8 5.6 2.2 Iris-virginica
133 6.3 2.8 5.1 1.5 Iris-virginica
134 6.1 2.6 5.6 1.4 Iris-virginica
135 7.7 3.0 6.1 2.3 Iris-virginica
136 6.3 3.4 5.6 2.4 Iris-virginica
137 6.4 3.1 5.5 1.8 Iris-virginica
138 6.0 3.0 4.8 1.8 Iris-virginica
139 6.9 3.1 5.4 2.1 Iris-virginica
140 6.7 3.1 5.6 2.4 Iris-virginica
141 6.9 3.1 5.1 2.3 Iris-virginica
142 5.8 2.7 5.1 1.9 Iris-virginica
143 6.8 3.2 5.9 2.3 Iris-virginica
144 6.7 3.3 5.7 2.5 Iris-virginica
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica
sepal length sepal width petal length petal width class
103 6.3 2.9 5.6 1.8 Iris-virginica
73 6.1 2.8 4.7 1.2 Iris-versicolor
135 7.7 3.0 6.1 2.3 Iris-virginica
64 5.6 2.9 3.6 1.3 Iris-versicolor
66 5.6 3.0 4.5 1.5 Iris-versicolor
.. ... ... ... ... ...
15 5.7 4.4 1.5 0.4 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
85 6.0 3.4 4.5 1.6 Iris-versicolor
55 5.7 2.8 4.5 1.3 Iris-versicolor
123 6.3 2.7 4.9 1.8 Iris-virginica
[148 rows x 5 columns]
sepal length sepal width petal length petal width class
103 6.3 2.9 5.6 1.8 Iris-virginica
73 6.1 2.8 4.7 1.2 Iris-versicolor
135 7.7 3.0 6.1 2.3 Iris-virginica
64 5.6 2.9 3.6 1.3 Iris-versicolor
66 5.6 3.0 4.5 1.5 Iris-versicolor
.. ... ... ... ... ...
31 5.4 3.4 1.5 0.4 Iris-setosa
124 6.7 3.3 5.7 2.1 Iris-virginica
49 5.0 3.3 1.4 0.2 Iris-setosa
131 7.9 3.8 6.4 2.0 Iris-virginica
4 5.0 3.6 1.4 0.2 Iris-setosa
[118 rows x 5 columns]
sepal length sepal width petal length petal width class
117 7.7 3.8 6.7 2.2 Iris-virginica
27 5.2 3.5 1.5 0.2 Iris-setosa
113 5.7 2.5 5.0 2.0 Iris-virginica
107 7.3 2.9 6.3 30.0 Iris-virginica
47 4.6 3.2 1.4 0.2 Iris-setosa
121 5.6 2.8 4.9 2.0 Iris-virginica
48 5.3 3.7 1.5 0.2 Iris-setosa
62 6.0 2.2 4.0 1.0 Iris-versicolor
9 4.9 3.1 1.5 0.1 Iris-setosa
5 5.4 3.9 1.7 0.4 Iris-setosa
86 6.7 3.1 4.7 1.5 Iris-versicolor
144 6.7 3.3 5.7 2.5 Iris-virginica
8 4.4 2.9 1.4 0.2 Iris-setosa
18 5.7 3.8 1.7 0.3 Iris-setosa
34 4.9 3.1 1.5 0.1 Iris-setosa
19 5.1 3.8 1.5 0.3 Iris-setosa
13 4.3 3.0 1.1 0.1 Iris-setosa
91 6.1 3.0 4.6 1.4 Iris-versicolor
33 5.5 4.2 1.4 0.2 Iris-setosa
44 5.1 3.8 1.9 0.4 Iris-setosa
68 6.2 2.2 4.5 1.5 Iris-versicolor
76 6.8 2.8 4.8 1.4 Iris-versicolor
89 5.5 2.5 4.0 1.3 Iris-versicolor
52 6.9 3.1 4.9 1.5 Iris-versicolor
24 4.8 3.4 1.9 0.2 Iris-setosa
15 5.7 4.4 1.5 0.4 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
85 6.0 3.4 4.5 1.6 Iris-versicolor
55 5.7 2.8 4.5 1.3 Iris-versicolor
123 6.3 2.7 4.9 1.8 Iris-virginica
103 Iris-virginica
73 Iris-versicolor
135 Iris-virginica
64 Iris-versicolor
66 Iris-versicolor
...
31 Iris-setosa
124 Iris-virginica
49 Iris-setosa
131 Iris-virginica
4 Iris-setosa
Name: class, Length: 118, dtype: object
sepal length sepal width petal length petal width
103 6.3 2.9 5.6 1.8
73 6.1 2.8 4.7 1.2
135 7.7 3.0 6.1 2.3
64 5.6 2.9 3.6 1.3
66 5.6 3.0 4.5 1.5
class
103 Iris-virginica
73 Iris-versicolor
135 Iris-virginica
64 Iris-versicolor
66 Iris-versicolor
sepal length sepal width petal length petal width
117 7.7 3.8 6.7 2.2
27 5.2 3.5 1.5 0.2
113 5.7 2.5 5.0 2.0
107 7.3 2.9 6.3 30.0
47 4.6 3.2 1.4 0.2
class
117 Iris-virginica
27 Iris-setosa
113 Iris-virginica
107 Iris-virginica
47 Iris-setosa
[[6.3 2.9 5.6 1.8]
[6.1 2.8 4.7 1.2]
[7.7 3. 6.1 2.3]]
七 源码地址
代码地址:
国内看 Gitee 之 pandas/机器学习数据预处理.py
国外看 GitHub 之 pandas/机器学习数据预处理.py
引用 莫烦 Python