在我們分析數(shù)據(jù)以及建立模型的過程中绝骚,需要花很多時(shí)間進(jìn)行數(shù)據(jù)的預(yù)處理:數(shù)據(jù)加載耐版、數(shù)據(jù)過濾、數(shù)據(jù)類型轉(zhuǎn)換或者排序等等压汪。這些處理占了80%甚至是更多的分析時(shí)間寥掐。有的時(shí)候呻拌,儲(chǔ)存在文件里或者數(shù)據(jù)庫里的數(shù)據(jù)格式并不能直接拿來分析擎鸠。許多研究人員需要將數(shù)據(jù)進(jìn)行處理馍盟,使用python, perl, R或者Java等一系列工具。其中穿香,Python為我們提供了一個(gè)高效舌狗、靈活的、快捷的工具扔水,使得我們可以對數(shù)據(jù)進(jìn)行操作痛侍。這一章節(jié),作者將講解數(shù)據(jù)處理過程里的幾個(gè)步驟魔市,包括處理缺失值主届,重復(fù)值,字符串處理等等待德。
這一篇筆記記錄的是如何處理缺失值NaN君丁。
丟失數(shù)據(jù)在許多數(shù)據(jù)分析應(yīng)用程序中經(jīng)常發(fā)生。其中一個(gè)目標(biāo)是使處理丟失數(shù)據(jù)的工作盡可能的方便快捷将宪。例如绘闷,默認(rèn)情況下橡庞,有關(guān)pandas對象的所有描述性統(tǒng)計(jì)信息都會(huì)排除丟失的數(shù)據(jù)。缺失數(shù)據(jù)在panda對象中表示的方式并不完美印蔗,但它對很多使用者都很有用扒最。對于數(shù)值數(shù)據(jù),pandas使用浮點(diǎn)值NaN(非數(shù)字)來表示丟失的數(shù)據(jù)华嘹。
In [1]: import pandas as pd
In [3]: import numpy as np
In [4]: string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
In [5]: string_data
Out[5]:
0 aardvark
1 artichoke
2 NaN
3 avocado
dtype: object
In [6]: string_data.isnull() #判斷是否為缺失值
Out[6]:
0 False
1 False
2 True
3 False
dtype: bool
你可以把某一個(gè)值手動(dòng)的賦一個(gè)缺失值:
In [7]: string_data[0] = None #None與NA是一樣的
In [8]: string_data.isnull()
Out[8]:
0 True
1 False
2 True
3 False
dtype: bool
判斷是否不為缺失值:
In [9]: string_data.notnull()
Out[9]:
0 False
1 True
2 False
3 True
dtype: bool
Filtering Out Missing Data
過濾缺失值:
In [11]: from numpy import nan as NA
In [12]: data = pd.Series([1, NA, 3.5, NA, 7])
In [13]: data
Out[13]:
0 1.0
1 NaN
2 3.5
3 NaN
4 7.0
dtype: float64
In [15]: data.dropna() #把NaN去掉
Out[15]:
0 1.0
2 3.5
4 7.0
dtype: float64
In [16]: data[data.notnull()] #第二種方法去掉NaN
Out[16]:
0 1.0
2 3.5
4 7.0
dtype: float64
上面是對Series數(shù)據(jù)結(jié)構(gòu)的處理方法吧趣,下面看一下對于dataframe的過濾方法:
In [17]: data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA],
...: [NA, NA, NA], [NA, 6.5, 3.]])
In [18]: data
Out[18]:
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
In [19]: data.dropna()
Out[19]:
0 1 2
0 1.0 6.5 3.0
這里你會(huì)發(fā)現(xiàn),對于dataframe耙厚,使用dropna
來過濾缺失值的時(shí)候强挫,只要你的dataframe里只要有一行含有NaN,那么它會(huì)把整行都去掉薛躬。如果你只想去掉那些一整行都是NaN的數(shù)據(jù)俯渤,可以使用下面的方法:
In [20]: data.dropna(how='all')
Out[20]:
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
3 NaN 6.5 3.0
這個(gè)方法只去掉了索引是2的那一行,因?yàn)檎卸际荖aN型宝。
那么怎么按照列來過濾數(shù)據(jù)呢八匠?
In [21]: data[4] =NA #先加都是NA的列
In [22]: data
Out[22]:
0 1 2 4
0 1.0 6.5 3.0 NaN
1 1.0 NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN 6.5 3.0 NaN
In [23]: data.dropna(axis=1,how='all') #把都是NA的列去掉
Out[23]:
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
同樣,你可以把dataframe其中的一些值變成NaN:
In [24]: df = pd.DataFrame(np.random.randn(7, 3)) #先生成一個(gè)dataframe
In [25]: df
Out[25]:
0 1 2
0 0.794614 -1.122838 -1.192451
1 0.309446 1.966428 -0.008502
2 -2.513006 -0.083181 1.092009
3 0.319553 0.148365 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
In [26]: df.iloc[:4, 1] = NA #把索引為1的列诡曙,索引從0-4(不包含4)的行的值變成NaN
In [27]: df
Out[27]:
0 1 2
0 0.794614 NaN -1.192451
1 0.309446 NaN -0.008502
2 -2.513006 NaN 1.092009
3 0.319553 NaN 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
In [28]: df.iloc[:2, 2] = NA #把索引為2的列臀叙,索引從0-2(不包含2)的行的值變成NaN
In [29]: df
Out[29]:
0 1 2
0 0.794614 NaN NaN
1 0.309446 NaN NaN
2 -2.513006 NaN 1.092009
3 0.319553 NaN 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
In [30]: df.dropna() #只要有NaN的行都刪除
Out[30]:
0 1 2
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
In [31]: df.dropna(thresh=2) #刪除那些包含2個(gè)NaN的行
Out[31]:
0 1 2
2 -2.513006 NaN 1.092009
3 0.319553 NaN 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
Filling In Missing Data
相比于去掉缺失值略水,有時(shí)你會(huì)想把缺失值填補(bǔ)上:
In [32]: df.fillna(0) #把所有缺失值都用0填補(bǔ)
Out[32]:
0 1 2
0 0.794614 0.000000 0.000000
1 0.309446 0.000000 0.000000
2 -2.513006 0.000000 1.092009
3 0.319553 0.000000 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
In [33]: df.fillna({1: 0.5, 2: 0}) #針對不同列的缺失值价卤,補(bǔ)充不同的值
Out[33]:
0 1 2
0 0.794614 0.500000 0.000000
1 0.309446 0.500000 0.000000
2 -2.513006 0.500000 1.092009
3 0.319553 0.500000 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
fillna
功能返回的是一個(gè)新的對象,你可以改變參數(shù)渊涝,使得返回值代替原來的dataframe:
In [34]: _ = df.fillna(0, inplace=True)
In [35]: df
Out[35]:
0 1 2
0 0.794614 0.000000 0.000000
1 0.309446 0.000000 0.000000
2 -2.513006 0.000000 1.092009
3 0.319553 0.000000 0.251443
4 -0.028759 0.223592 -0.757231
5 1.154804 1.139824 -0.140732
6 -0.407429 0.523816 -0.619919
除了 fillna
功能可以對缺失值進(jìn)行填充慎璧,還有一種方法是ffill
:
In [36]: df = pd.DataFrame(np.random.randn(6, 3)) #構(gòu)建一個(gè)dataframe
In [37]: df.iloc[2:, 1] = NA #加入NaN值
In [38]: df.iloc[4:, 2] = NA #加入NaN值
In [39]: df
Out[39]:
0 1 2
0 -1.387958 0.550978 0.864804
1 0.486326 0.664703 -0.259249
2 -0.745425 NaN -1.389911
3 -0.532680 NaN 0.212723
4 1.530230 NaN NaN
5 0.880760 NaN NaN
In [40]: df.fillna(method='ffill') #ffill是指用缺失值的上面一個(gè)值來填充缺失值
Out[40]:
0 1 2
0 -1.387958 0.550978 0.864804
1 0.486326 0.664703 -0.259249
2 -0.745425 0.664703 -1.389911
3 -0.532680 0.664703 0.212723
4 1.530230 0.664703 0.212723
5 0.880760 0.664703 0.212723
In [41]: df.fillna(method='ffill', limit=2) #也可以規(guī)定只填充幾個(gè)缺失值,剩下的依舊保留
Out[41]:
0 1 2
0 -1.387958 0.550978 0.864804
1 0.486326 0.664703 -0.259249
2 -0.745425 0.664703 -1.389911
3 -0.532680 0.664703 0.212723
4 1.530230 NaN 0.212723
5 0.880760 NaN 0.212723
fillna
還有其他的一些用法跨释,比如說:
In [42]: data = pd.Series([1., NA, 3.5, NA, 7])
In [43]: data
Out[43]:
0 1.0
1 NaN
2 3.5
3 NaN
4 7.0
dtype: float64
In [44]: data.fillna(data.mean()) #填補(bǔ)的值是其他3個(gè)值的平均值
Out[44]:
0 1.000000
1 3.833333
2 3.500000
3 3.833333
4 7.000000
dtype: float64