5.5 数据预处理

来源:互联网 发布:mysql创建序列sql语句 编辑:程序博客网 时间:2024/05/22 15:32

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

5.5.1 数据缺失处理

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

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

运行结果

0    abcd1    efgh2    ijkl3    mnopdtype: object0    False1    False2    False3    Falsedtype: bool

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

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

运行结果:

0    1.02    3.54    7.0dtype: 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 npimport pandas as pdfrom numpy import nan as NAdfdata = pd.DataFrame(np.random.randn(7,3))dfdata.ix[:4, 1] = NAdfdata.ix[:2, 2] = NAprint(dfdata)print('\n')print(dfdata.dropna(thresh=2))

运行结果:

          0         1         20  0.555364       NaN       NaN1 -0.040936       NaN       NaN2 -0.213490       NaN       NaN3  1.142304       NaN  0.0382454  1.888789       NaN  1.2196065  1.300171  0.843961 -0.2324806 -0.457737  0.298572 -0.105454          0         1         23  1.142304       NaN  0.0382454  1.888789       NaN  1.2196065  1.300171  0.843961 -0.2324806 -0.457737  0.298572 -0.105454

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

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

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

print(dfdata.fillna(value=0))

运行结果:

          0         1         20  0.555364  0.000000  0.0000001 -0.040936  0.000000  0.0000002 -0.213490  0.000000  0.0000003  1.142304  0.000000  0.0382454  1.888789  0.000000  1.2196065  1.300171  0.843961 -0.2324806 -0.457737  0.298572 -0.105454

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

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

运行结果:

          0         1         20  0.819655       NaN       NaN1 -0.765497       NaN       NaN2  1.355599       NaN       NaN3  0.174048       NaN  1.4966944 -1.966648       NaN -0.5989365 -2.844108  1.175119  0.6855966 -1.352572  0.575769  0.097997          0           1           20  0.819655  111.000000  222.0000001 -0.765497  111.000000  222.0000002  1.355599  111.000000  222.0000003  0.174048  111.000000    1.4966944 -1.966648  111.000000   -0.5989365 -2.844108    1.175119    0.6855966 -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.01    NaN2    3.53    NaN4    7.0dtype: float640    1.0000001    3.8333332    3.5000003    3.8333334    7.000000dtype: float640    1.01    3.52    3.53    3.54    7.0dtype: 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            3count  1000.000000  1000.000000  1000.000000  1000.000000mean     -0.012398     0.004329    -0.044018     0.006960std       1.019043     1.015391     1.035915     0.991017min      -3.026647    -2.816855    -3.509064    -2.92608425%      -0.702266    -0.688002    -0.768781    -0.69416050%      -0.026979    -0.033296    -0.074148    -0.00515175%       0.643268     0.715220     0.657117     0.690144max       3.386927     3.728271     3.336689     3.009779964    3.009779Name: 3, dtype: float64

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

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

运行结果:

            0         1         2         33    0.880152 -1.845595 -3.062386 -0.377484170  0.330547  3.728271  1.038236  0.096751175 -3.026647 -0.221601  0.488011 -1.296075205 -1.889809  3.086899  0.240812 -0.819182341  0.689361 -0.726927  3.336689 -0.399356489  0.583099 -0.892590 -3.509064 -0.086007565 -0.203513 -0.242532 -3.022158  1.225842815 -0.172945 -1.968579  3.015868  0.528105835  3.386927  0.144197 -0.515101 -1.268720964  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  k20  one   11  one   12  one   23  two   24  two   35  two   36  two   40    False1     True2    False3    False4    False5     True6    Falsedtype: 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  k20  one   11  one   12  one   23  two   24  two   35  two   36  two   4    k1  k20  one   12  one   23  two   24  two   36  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  v10  one   1   01  one   1   12  one   2   23  two   2   34  two   3   45  two   3   56  two   4   6    k1  k2  v10  one   1   03  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  v10  one   1   01  one   1   12  one   2   23  two   2   34  two   3   45  two   3   56  two   4   6    k1  k2  v11  one   1   12  one   2   23  two   2   35  two   3   56  two   4   6