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