数据预处理主要包括缺失值处理、重复值处理和异常值的处理
缺失值
首先创建一个实例数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
data=[[np.nan,54,'男','2018/8/8'],
[np.nan,16,np.nan,'2018/8/9'],
['A3',47,'女','2018/8/10'],
['A4',41,'男','2018/8/11'],
[np.nan,np.nan,np.nan,np.nan]]
columns=['编号','年龄','性别','注册时间']
df = pd.DataFrame(data=data,columns=columns)
缺失值的查看
缺失值查看的方式有多种,df.info(),df.isnull(),df.isnull().sum()均可以查看缺失值,具体的区别如下。
df.info()返回各列数据的类型、非空值的个数,通过查看非空值的个数可以明确各列缺失值,返回信息如下
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 编号 2 non-null object
1 年龄 4 non-null float64
2 性别 3 non-null object
3 注册时间 4 non-null object
dtypes: float64(1), object(3)
memory usage: 288.0+ bytes
df.isnull()返回存储布尔值的表,如果对应空值即为True,如果对应非空值即为False
df.isnull()
编号 年龄 性别 注册时间
0 True False False False
1 True False True False
2 False False False False
3 False False False False
4 True True True True
df.isnull().sum() 通过在sum中设置axis=0或axis=1,查看各列或各行空值个数
df.isnull().sum(axis=0)
编号 3
年龄 1
性别 2
注册时间 1
dtype: int64
df.isnull().sum(axis=1)
0 1
1 2
2 0
3 0
4 4
dtype: int64
缺失值的处理
删除缺失值
df.dropna()删除缺失值,这里默认删除行,比较关键的参数为how,thresh和inplace
how 可选 'any', 'all',默认为 'any','any'意思为存在缺失值时删除该行或列,'all'意思为全部为缺失值时删除该行或列
thresh 用来设置阈值,即要求非空值的个数,因为如果某行或列空值不是很多时一般还是需要保留,此时通过thresh可以实现
inplace 默认False,返回一个新的DataFrame,设置为True时即修改原DataFrame
df.dropna(how='all')
编号 年龄 性别 注册时间
0 NaN 54.0 男 2018/8/8
1 NaN 16.0 NaN 2018/8/9
2 A3 47.0 女 2018/8/10
3 A4 41.0 男 2018/8/11
填充缺失值
可以填充一个输入的常数、平均值、众数等,由于各列数据一般不同,因此常常分列填充,也可以根据空值前后非空值进行填充
- 填充常数
在df.fillna()括号书输入一个以列名为key,以替换值为value的字典可以实现分列填充
df.fillna({'编号':'A5','年龄':19,'性别':'男','注册时间':'2018/8/12'})
编号 年龄 性别 注册时间
0 A5 54.0 男 2018/8/8
1 A5 16.0 男 2018/8/9
2 A3 47.0 女 2018/8/10
3 A4 41.0 男 2018/8/11
4 A5 19.0 男 2018/8/12
- 填充平均值
与填充常数基本相同,只是需要用平均值
df.fillna({'年龄':df['年龄'].mean()})
编号 年龄 性别 注册时间
0 NaN 54.0 男 2018/8/8
1 NaN 16.0 NaN 2018/8/9
2 A3 47.0 女 2018/8/10
3 A4 41.0 男 2018/8/11
4 NaN 39.5 NaN NaN
- 填充众数
与填充常数基本相同,只是需要用众数,不过这里需要注意DataFrame求众数时返回的是Series类型
df.fillna({'性别':df['性别'].mode()[0]})
编号 年龄 性别 注册时间
0 NaN 54.0 男 2018/8/8
1 NaN 16.0 男 2018/8/9
2 A3 47.0 女 2018/8/10
3 A4 41.0 男 2018/8/11
4 NaN NaN 男 NaN
- 根据前后值填充
df.fillna()中需要设置method参数,method='ffill'利用前值填充,method='bfill'利用后值填充
df.fillna(method='bfill')
编号 年龄 性别 注册时间
0 A3 54.0 男 2018/8/8
1 A3 16.0 女 2018/8/9
2 A3 47.0 女 2018/8/10
3 A4 41.0 男 2018/8/11
4 NaN NaN NaN NaN
df.fillna(method='ffill')
编号 年龄 性别 注册时间
0 NaN 54.0 男 2018/8/8
1 NaN 16.0 男 2018/8/9
2 A3 47.0 女 2018/8/10
3 A4 41.0 男 2018/8/11
4 A4 41.0 男 2018/8/11
除了这种简单方法填充,也可以根据机器学习模型如随机森林等方法填充某列的缺失值 ,这里暂不详细介绍