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部分提及的一些插值方法。