5.5 数据预处理

2017-04-17  本文已影响0人  操作系统

数据预处理包括对收集的数据进行数据缺失处理、检测和过滤异常值及移除重复数据等步骤。

5.5.1 数据缺失处理

数据缺失在大部分数据分析应用中都很常见,Pandas使用NaN(Not a number)表示浮点和非浮点数组中的缺失数据。处理缺失数据的方法有四种:dropna,fillna,isnull,notnull。
is(not) null,这一对方法对对象做元素级的应用,然后返回一个布尔型数组,一般可用于布尔型索引。示例代码:

import pandas as pd
s = pd.Series(['abcd', 'efgh', 'ijkl', 'mnop'])
print(s)
print('\n')
print(s.isnull())

运行结果

0    abcd
1    efgh
2    ijkl
3    mnop
dtype: object


0    False
1    False
2    False
3    False
dtype: bool

dropna,对于一个Series,dropna返回一个仅含非空数据和索引值的Series。示例代码:

import pandas as pd
from numpy import nan as NA
sdata = pd.Series([1, NA, 3.5, NA, 7])
print(sdata.dropna())

运行结果:

0    1.0
2    3.5
4    7.0
dtype: float64

对于DataFrame的处理方式,一旦使用drop命令,至少要弃掉一行或一列。解决的方法是通过一个额外的参数,形式如下:

dropna(axis=0, how='any', thresh=None)

axis轴参数可选值为0或1,默认值为0表示以列为标准删除缺失值,1则表示以行为标准删除。how参数可选的值为any或者all,all仅在切片元素全为NA时才抛弃该行(列)。thresh为整数类型,如thresh=3表示一行当中至少有三个NA值才将其保留。假设只想留一部分观察数据,可以用thresh参数实现此目的,示例代码:

import numpy as np
import pandas as pd
from numpy import nan as NA
dfdata = pd.DataFrame(np.random.randn(7,3))
dfdata.ix[:4, 1] = NA
dfdata.ix[:2, 2] = NA
print(dfdata)
print('\n')
print(dfdata.dropna(thresh=2))

运行结果:

          0         1         2
0  0.555364       NaN       NaN
1 -0.040936       NaN       NaN
2 -0.213490       NaN       NaN
3  1.142304       NaN  0.038245
4  1.888789       NaN  1.219606
5  1.300171  0.843961 -0.232480
6 -0.457737  0.298572 -0.105454


          0         1         2
3  1.142304       NaN  0.038245
4  1.888789       NaN  1.219606
5  1.300171  0.843961 -0.232480
6 -0.457737  0.298572 -0.105454

如果不想滤除缺失的数据,而是通过其他方式填补“空洞”,fillna是最主要的函数。fillna表示对缺失数据进行设定填充,形式如下:

fillna(value=None, method=None, axis=0)

fillna会将缺失值替换为参数value设置的常数。示例代码:

print(dfdata.fillna(value=0))

运行结果:

          0         1         2
0  0.555364  0.000000  0.000000
1 -0.040936  0.000000  0.000000
2 -0.213490  0.000000  0.000000
3  1.142304  0.000000  0.038245
4  1.888789  0.000000  1.219606
5  1.300171  0.843961 -0.232480
6 -0.457737  0.298572 -0.105454

而value参数除了基本类型外,还可以使用字典,这样可以实现对不同列填充不同的值。示例代码:

dfdata = pd.DataFrame(np.random.randn(7,3))
dfdata.ix[:4, 1] = NA
dfdata.ix[:2, 2] = NA
print(dfdata)
print('\n')
print(dfdata.fillna(value={1:111,2:222}))

运行结果:

          0         1         2
0  0.819655       NaN       NaN
1 -0.765497       NaN       NaN
2  1.355599       NaN       NaN
3  0.174048       NaN  1.496694
4 -1.966648       NaN -0.598936
5 -2.844108  1.175119  0.685596
6 -1.352572  0.575769  0.097997


          0           1           2
0  0.819655  111.000000  222.000000
1 -0.765497  111.000000  222.000000
2  1.355599  111.000000  222.000000
3  0.174048  111.000000    1.496694
4 -1.966648  111.000000   -0.598936
5 -2.844108    1.175119    0.685596
6 -1.352572    0.575769    0.097997

除了填充设定的已有值,也可以利用fillna实现许多别的功能,比如可以传入Series的平均值或中位数,示例代码:

sdata = pd.Series([1.0, NA, 3.5, NA, 7])
print(sdata)
print('\n')
print(sdata.fillna(value=sdata.mean()))
print('\n')
print(sdata.fillna(value=sdata.median()))

运行结果:

0    1.0
1    NaN
2    3.5
3    NaN
4    7.0
dtype: float64


0    1.000000
1    3.833333
2    3.500000
3    3.833333
4    7.000000
dtype: float64


0    1.0
1    3.5
2    3.5
3    3.5
4    7.0
dtype: float64

5.5.2 检测和过滤异常值

异常值(outlier)的过滤或变换运算在很大程度上就是数组运算。如在形为(1000,4)的标准正态分布数组中,找出某一列中绝对值大小超过3的项,并做去除(drop)操作,示例代码:

data = pd.DataFrame(np.random.randn(1000,4))
print(data.describe())
print('\n')
col=data[3]
print(col[np.abs(col)>3])

运行结果:

                 0            1            2            3
count  1000.000000  1000.000000  1000.000000  1000.000000
mean     -0.012398     0.004329    -0.044018     0.006960
std       1.019043     1.015391     1.035915     0.991017
min      -3.026647    -2.816855    -3.509064    -2.926084
25%      -0.702266    -0.688002    -0.768781    -0.694160
50%      -0.026979    -0.033296    -0.074148    -0.005151
75%       0.643268     0.715220     0.657117     0.690144
max       3.386927     3.728271     3.336689     3.009779


964    3.009779
Name: 3, dtype: float64

以上结果是找出第3列绝对值大于3的行标索引。如果要找出任意列绝对值超过3的值的所有行标,示例代码:

print(data[(np.abs(data)>3).any(1)])

运行结果:


            0         1         2         3
3    0.880152 -1.845595 -3.062386 -0.377484
170  0.330547  3.728271  1.038236  0.096751
175 -3.026647 -0.221601  0.488011 -1.296075
205 -1.889809  3.086899  0.240812 -0.819182
341  0.689361 -0.726927  3.336689 -0.399356
489  0.583099 -0.892590 -3.509064 -0.086007
565 -0.203513 -0.242532 -3.022158  1.225842
815 -0.172945 -1.968579  3.015868  0.528105
835  3.386927  0.144197 -0.515101 -1.268720
964  0.652401  1.830282 -1.054405  3.009779

通过DataFrame的drop()方法,可以对异常值进行删除操作,示例代码:

data.drop(data[np.abs(data)>3])

5.5.3

DataFrame的duplicated()方法返回一个布尔型Series,表示各行是否是重复行。示例代码:

data = pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1, 1, 2, 2, 3, 3, 4]})
print(data)
print('\n')
print(data.duplicated())

运行结果:

    k1  k2
0  one   1
1  one   1
2  one   2
3  two   2
4  two   3
5  two   3
6  two   4


0    False
1     True
2    False
3    False
4    False
5     True
6    False
dtype: bool

与此相关的还有一个drop_duplicates()方法,它用于返回一个移除了重复行的DataFrame,示例代码:

data = pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1, 1, 2, 2, 3, 3, 4]})
print(data)
print('\n')
print(data.drop_duplicates())

运行结果:

    k1  k2
0  one   1
1  one   1
2  one   2
3  two   2
4  two   3
5  two   3
6  two   4


    k1  k2
0  one   1
2  one   2
3  two   2
4  two   3
6  two   4

上面的两个方法会默认判断全部列,也可以指定部分列进行重复项判断,假设还有一列值,而只希望根据k1列过滤重复项。示例代码:

data = pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1, 1, 2, 2, 3, 3, 4]})
data['v1']=range(7)
print(data)
print('\n')
print(data.drop_duplicates(['k1']))

运行结果:

    k1  k2  v1
0  one   1   0
1  one   1   1
2  one   2   2
3  two   2   3
4  two   3   4
5  two   3   5
6  two   4   6


    k1  k2  v1
0  one   1   0
3  two   2   3

duplicated和drop_duplicates默认保留第一个出现的值的组合。传入take_last=True则保留最后一个,示例代码:

data = pd.DataFrame({'k1':['one']*3+['two']*4, 'k2':[1, 1, 2, 2, 3, 3, 4]})
data['v1']=range(7)
print(data)
print('\n')
print(data.drop_duplicates(['k1','k2'], take_last=True))

运行结果:

    k1  k2  v1
0  one   1   0
1  one   1   1
2  one   2   2
3  two   2   3
4  two   3   4
5  two   3   5
6  two   4   6


    k1  k2  v1
1  one   1   1
2  one   2   2
3  two   2   3
5  two   3   5
6  two   4   6
上一篇下一篇

猜你喜欢

热点阅读