添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

21. Pandas的数据清洗-填充NaN

上一章介绍了如何查询数据里的NaN数据,以及删除NaN的问题,有的时候不是说仅仅删除了NaN就对,实际出现NaN数据的原因很多,对于NaN数据所在的行或者列可以进行必要的数据填充,本章介绍一些简单的处理方法来填充NaN所在的行或者列,而不是删除NaN行、列数据。

21.1 0填充NaN数据

对于DataFrame里的数据NaN可以使用0来填充,使用fillna函数。

import pandas as pd
import numpy as np
val = np.arange(10, 38).reshape(7, 4)
col = list("abcd")
idx = "cake make fake sake wake lake take".split()
df = pd.DataFrame(val, columns = col, index = idx)
df["e"] = np.nan
df.at["make", "e"] = 100
df["f"] = np.nan
df.loc["gake"] = np.nan 
print df
df.fillna(0,inplace = True)
print df

程序执行结果如下:

       a   b   c   d    e   f
cake  10  11  12  13  NaN NaN
make  14  15  16  17  100 NaN
fake  18  19  20  21  NaN NaN
sake  22  23  24  25  NaN NaN
wake  26  27  28  29  NaN NaN
lake  30  31  32  33  NaN NaN
take  34  35  36  37  NaN NaN
gake NaN NaN NaN NaN  NaN NaN
       a   b   c   d    e  f
cake  10  11  12  13    0  0
make  14  15  16  17  100  0
fake  18  19  20  21    0  0
sake  22  23  24  25    0  0
wake  26  27  28  29    0  0
lake  30  31  32  33    0  0
take  34  35  36  37    0  0
gake   0   0   0   0    0  0

21.2 前向或后向数据填充

前向或后向填充NaN数据的意思是用NaN前一行(方向是往后的)或者后一行的数据填充NaN。还是使用fillna函数,只不过形参里设定method='ffill'method='bfill'

import pandas as pd
import numpy as np
val = np.arange(10, 38).reshape(7, 4)
col = list("abcd")
idx = "cake make fake sake wake lake take".split()
df = pd.DataFrame(val, columns = col, index = idx)
df["e"] = np.nan
df.at["fake", "e"] = 100
df.at["lake", "e"] = 500
df["f"] = np.nan
df.loc["gake"] = np.nan 
df.at["gake", "c"] = 700
print "**1****************************\n", df
df["e"].fillna(method = 'ffill',inplace=True)
print "**2****************************\n", df
df["e"].fillna(method = 'bfill',inplace=True)
print "**3****************************\n", df
df.loc["gake"].fillna(method = 'bfill',inplace=True, axis = 0)
print "**4****************************\n", df
df.loc["gake"].fillna(method = 'bfill',inplace=True, axis = 0)
print "**5****************************\n", df
df.fillna(method = 'ffill',inplace=True, axis = 1)
print "**6****************************\n", df

程序执行结果:

**1****************************
       a   b    c   d    e   f
cake  10  11   12  13  NaN NaN
make  14  15   16  17  NaN NaN
fake  18  19   20  21  100 NaN
sake  22  23   24  25  NaN NaN
wake  26  27   28  29  NaN NaN
lake  30  31   32  33  500 NaN
take  34  35   36  37  NaN NaN
gake NaN NaN  700 NaN  NaN NaN
**2****************************
       a   b    c   d    e   f
cake  10  11   12  13  NaN NaN
make  14  15   16  17  NaN NaN
fake  18  19   20  21  100 NaN
sake  22  23   24  25  100 NaN
wake  26  27   28  29  100 NaN
lake  30  31   32  33  500 NaN
take  34  35   36  37  500 NaN
gake NaN NaN  700 NaN  500 NaN
**3****************************
       a   b    c   d    e   f
cake  10  11   12  13  100 NaN
make  14  15   16  17  100 NaN
fake  18  19   20  21  100 NaN
sake  22  23   24  25  100 NaN
wake  26  27   28  29  100 NaN
lake  30  31   32  33  500 NaN
take  34  35   36  37  500 NaN
gake NaN NaN  700 NaN  500 NaN
**4****************************
        a    b    c    d    e   f
cake   10   11   12   13  100 NaN
make   14   15   16   17  100 NaN
fake   18   19   20   21  100 NaN
sake   22   23   24   25  100 NaN
wake   26   27   28   29  100 NaN
lake   30   31   32   33  500 NaN
take   34   35   36   37  500 NaN
gake  700  700  700  500  500 NaN
**5****************************
        a    b    c    d    e   f
cake   10   11   12   13  100 NaN
make   14   15   16   17  100 NaN
fake   18   19   20   21  100 NaN
sake   22   23   24   25  100 NaN
wake   26   27   28   29  100 NaN
lake   30   31   32   33  500 NaN
take   34   35   36   37  500 NaN
gake  700  700  700  500  500 NaN
**6****************************
        a    b    c    d    e    f
cake   10   11   12   13  100  100
make   14   15   16   17  100  100
fake   18   19   20   21  100  100
sake   22   23   24   25  100  100
wake   26   27   28   29  100  100
lake   30   31   32   33  500  500
take   34   35   36   37  500  500
gake  700  700  700  500  500  500

21.3 用Series填充某列某行值

可以给出一个Series数据(label和DataFrame的label有相同的)去填充DataFrame对应行(label)的数据。

import pandas as pd
import numpy as np
val = np.arange(10, 38).reshape(7, 4)
col = list("abcd")
idx = "cake make fake sake wake lake take".split()
df = pd.DataFrame(val, columns = col, index = idx)
df["e"] = np.nan
df.at["fake", "e"] = 100
df.at["lake", "e"] = 500
df["f"] = np.nan
df.loc["gake"] = np.nan 
df.at["gake", "c"] = 700
fill = pd.Series([123, 321, 213],index =["cake", "wake", "gake"] )
print df
df["e"].fillna(fill,inplace=True)
df["f"].fillna(fill,inplace=True)
print df

程序执行的结果:

       a   b    c   d    e   f
cake  10  11   12  13  NaN NaN
make  14  15   16  17  NaN NaN
fake  18  19   20  21  100 NaN
sake  22  23   24  25  NaN NaN
wake  26  27   28  29  NaN NaN
lake  30  31   32  33  500 NaN
take  34  35   36  37  NaN NaN
gake NaN NaN  700 NaN  NaN NaN
       a   b    c   d    e    f
cake  10  11   12  13  123  123
make  14  15   16  17  NaN  NaN
fake  18  19   20  21  100  NaN
sake  22  23   24  25  NaN  NaN
wake  26  27   28  29  321  321
lake  30  31   32  33  500  NaN
take  34  35   36  37  NaN  NaN
gake NaN NaN  700 NaN  213  213

21.4 插值填充数据

利用插值函数interpolate()对列向的数据进行填值。实现插值填充数据,那么要求这列上必须得有一些数据才可以,至少2个,会对起点和终点间的NaN进行插值。

import pandas as pd
import numpy as np
val = np.arange(10, 38).reshape(7, 4)
col = list("abcd")
idx = "cake make fake sake wake lake take".split()
df = pd.DataFrame(val, columns = col, index = idx)
df["e"] = np.nan
df.at["fake", "e"] = 100
df.at["lake", "e"] = 600
df["f"] = np.nan
df.loc["gake"] = np.nan 
df.at["gake", "c"] = 700
print df
df["e"].interpolate(inplace=True)
df["f"].interpolate(inplace=True)
print df

程序的执行结果:

       a   b    c   d    e   f
cake  10  11   12  13  NaN NaN
make  14  15   16  17  NaN NaN
fake  18  19   20  21  100 NaN
sake  22  23   24  25  NaN NaN
wake  26  27   28  29  NaN NaN
lake  30  31   32  33  600 NaN
take  34  35   36  37  NaN NaN
gake NaN NaN  700 NaN  NaN NaN
       a   b    c   d           e   f
cake  10  11   12  13         NaN NaN
make  14  15   16  17         NaN NaN
fake  18  19   20  21  100.000000 NaN
sake  22  23   24  25  266.666667 NaN
wake  26  27   28  29  433.333333 NaN
lake  30  31   32  33  600.000000 NaN
take  34  35   36  37  600.000000 NaN
gake NaN NaN  700 NaN  600.000000 NaN

pandas的插值支持很多的插值方法可以参考本网站SciPy部分提及的一些插值方法。