pandas数据清洗
数据清洗的原因
在原始数据中存在:
- 缺失值
- 异常值
- 重复值
处理空值
两种空值
- None
- 类型为None对象,不能参与运算
- np.nan
- 类型为float,可以参与运算
pandas处理空值的方法
- isnull
- notnull
- any
- all
- dropna
- fillna
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
# 伪造一些数据(存在空值)
df = DataFrame(data=np.random.randint(0,10,size=(8,6)))
print(df)
----------------------------------------------------------
0 1 2 3 4 5
0 7 0 2 6 2 5
1 9 7 4 2 7 6
2 4 9 8 3 9 8
3 8 5 4 4 8 8
4 7 1 0 0 8 2
5 1 2 7 4 4 8
6 6 2 0 7 2 2
7 9 5 6 6 7 2
----------------------------------------------------------
df.iloc[2,3] = None
df.iloc[4,4] = np.nan
df.iloc[5,2] = None
print(df)
----------------------------------------------------------
0 1 2 3 4 5
0 7 0 2.0 6.0 2.0 5
1 9 7 4.0 2.0 7.0 6
2 4 9 8.0 NaN 9.0 8
3 8 5 4.0 4.0 8.0 8
4 7 1 0.0 0.0 NaN 2
5 1 2 NaN 4.0 4.0 8
6 6 2 0.0 7.0 2.0 2
7 9 5 6.0 6.0 7.0 2
----------------------------------------------------------
print(df.isnull()) # 对空值进行过滤
----------------------------------------------------------
0 1 2 3 4 5
0 False False False False False False
1 False False False False False False
2 False False False True False False
3 False False False False False False
4 False False False False True False
5 False False True False False False
6 False False False False False False
7 False False False False False False
----------------------------------------------------------
print(df.isnull().any(axis=1)) # 查看行或列中是否有空值
----------------------------------------------------------
0 False
1 False
2 True
3 False
4 True
5 True
6 False
7 False
dtype: bool
----------------------------------------------------------
# 将上方结果作为原数据的行索引
print(df.loc[df.isnull().any(axis=1)])
----------------------------------------------------------
0 1 2 3 4 5
2 4 9 8.0 NaN 9.0 8
4 7 1 0.0 0.0 NaN 2
5 1 2 NaN 4.0 4.0 8
----------------------------------------------------------
print(df.loc[df.isnull().any(axis=1)].index)
----------------------------------------------------------
Int64Index([2, 4, 5], dtype='int64')
----------------------------------------------------------
# 删除有空数据的行
drop_index = df.loc[df.isnull().any(axis=1)].index
print(df.drop(labels=drop_index,axis=0))
----------------------------------------------------------
0 1 2 3 4 5
0 7 0 2.0 6.0 2.0 5
1 9 7 4.0 2.0 7.0 6
3 8 5 4.0 4.0 8.0 8
6 6 2 0.0 7.0 2.0 2
7 9 5 6.0 6.0 7.0 2
----------------------------------------------------------
# 删除缺失值所在行方法二
df.loc[df.notnull().all(axis=1)]
----------------------------------------------------------
0 1 2 3 4 5
0 7 0 2.0 6.0 2.0 5
1 9 7 4.0 2.0 7.0 6
3 8 5 4.0 4.0 8.0 8
6 6 2 0.0 7.0 2.0 2
7 9 5 6.0 6.0 7.0 2
----------------------------------------------------------
# 对缺失值进行覆盖填充
df.fillna(method='ffill') # ffill 前填充 bfill后填充
去除重复值
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False)
参数
subset : column label or sequence of labels, optional
用来指定特定的列,默认所有列
keep : {‘first’, ‘last’, False}, default ‘first’
删除重复项并保留第一次出现的项
inplace : boolean, default False
是直接在原来数据上修改还是保留一个副本
实战
第一种情况,去掉重复的数据:
### 构造数据
data = pd.DataFrame(data=[['a',1],['a',2],['b',1],['b',2],['a',1]],columns=['label','num'])
data
Out[17]:
label num
0 a 1
1 a 2
2 b 1
3 b 2
4 a 1
Dataframe已经有相关的函数来处理这个问题,就是drop_duplicates()函数。我们看到下面已经把重复的(’a',1)已经删除了。具体的参数大家可以点击链接,参考官方文档。总共只有三个参数。
data.drop_duplicates()
Out[18]:
label num
0 a 1
1 a 2
2 b 1
3 b 2
我们也可以利用subset参数指定去除某一列的重复值。
data.drop_duplicates(subset='label')
Out[20]:
label num
0 a 1
2 b 1
第二种情况,从数据中提取重复的数据:
DataFrame也提供了相关的函数来处理这个问题,就是duplicated()函数。我们可以看到duplicated函数返回的是布尔类型,重复出现就返回True。该函数只有两个参数,大家可以参考官方文档。
data.duplicated()
Out[40]:
0 False
1 False
2 False
3 False
4 True
dtype: bool
因为keep参数默认为First,就是除了第一次出现的数据,其他重复的数据都标记为True;如果我们想要获取所有重复的数据,可以将keep的值赋值为False。如下所示,就可以提取出所有重复的数据。
data.duplicated(keep=False)
Out[41]:
0 True
1 False
2 False
3 False
4 True
dtype: bool
因为duplicated函数返回的是布尔类型,所以要想得到具体的数据可以做如下操作:
data[data.duplicated(keep=False)]
Out[42]:
label num
0 a 1
4 a 1
Pandas异常值处理
import pandas as pd
#生成异常数据
df=pd.DataFrame({'col1':[1,120,3,5,2,12,13],
'col2':[12,17,31,53,22,32,43]})
print(df)
col1 col2
0 1 12
1 120 17
2 3 31
3 5 53
4 2 22
5 12 32
6 13 43
df_zscore=df.copy() #复制一个用来存储Z-score得分的数据框
cols=df.columns
for col in cols:
df_col=df[col]
z_score=(df_col - df_col.mean()) / df_col.std() #计算每列的Z-score得分
df_zscore[col] = z_score.abs() > 2.2 #判断Z-score得分是否大于2.2,如果是则为True,否则为False
#打印,为True即异常值
print(df_zscore)
col1 col2
0 False False
1 True False
2 False False
3 False False
4 False False
5 False False
6 False False
#获取无异常值的数据
df_drop_outlier=df[df_zscore['col1']==False]
#打印
print(df_drop_outlier)
col1 col2
0 1 12
2 3 31
3 5 53
4 2 22
5 12 32
6 13 43