Pandas数据清洗


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