Pandas简明教程:七、Pandas缺失数据的处理(数据清洗基础)
文章目錄
- 1、缺失數(shù)據(jù)的類(lèi)型
- 2、定位缺失數(shù)據(jù)
- 3、修改定位數(shù)據(jù)
- 4、批量修改缺失數(shù)據(jù)
- 5、數(shù)據(jù)修復(fù)的利器--插值法(`interpolate`)
- 本系列教程教程完整目錄:
數(shù)據(jù)清洗的內(nèi)容其實(shí)很豐富,其中最基本的問(wèn)題就是對(duì)一些缺失數(shù)據(jù)的處理。比如我們常會(huì)看到這樣的表:
| 0 | 100 | 30 | |
| 1 | 90 | 45 | 40 |
| 2 | 56 | 80 | |
| 3 | 95 | 98 |
在普遍的辦公場(chǎng)景下(尤其是一些重要的表格),通常都有可能是有特殊的情況,那么此時(shí)都一定會(huì)去手動(dòng)修改,甚至有時(shí)還會(huì)特別麻煩(比如銀行的某些信息)。但我們?cè)诟?jìng)賽中,研究中,做項(xiàng)目的過(guò)程中對(duì)這些數(shù)據(jù)就可以自由一點(diǎn),希望能利用經(jīng)驗(yàn)知識(shí)等來(lái)對(duì)它們進(jìn)行一定的處理。
本文就從這類(lèi)問(wèn)題入手講解一下在Pandas中如何處理這些數(shù)據(jù)。
1、缺失數(shù)據(jù)的類(lèi)型
據(jù)官方文檔描述,由于在Python中None就是默認(rèn)的空值類(lèi)型,因此它首先就會(huì)被當(dāng)作缺失數(shù)據(jù)處理。
其次Nan (not a number)也是常見(jiàn)的空值或者異常數(shù)據(jù)類(lèi)型。
同時(shí),官網(wǎng)說(shuō)道:+-inf也可以被視作缺失數(shù)據(jù),此時(shí)需要加設(shè)一句:
pandas.options.mode.use_inf_as_na = True比如上面的數(shù)據(jù)如果以逗號(hào)分隔存入csv文件,再讀取出來(lái)時(shí)是這樣:
df = pd.read_csv(r".\test_nan.csv") # 數(shù)據(jù)存在該文件中dfUnnamed: 0 First Score Second Score Third Score 0 0 100.0 30.0 NaN 1 1 90.0 45.0 40.0 2 2 NaN 56.0 80.0 3 3 95.0 NaN 98.0這里顯示的第一列是Index,第二列Unnamed:0是由于這一個(gè)位置是空,于是被自動(dòng)命名為"未命名"表頭。而這里我們能清楚地看到,表中的空行已經(jīng)被顯示為NaN。
不過(guò)要注意的是,此時(shí)如果csv文件中這些空值位置是空格或者Tab的話(huà),它會(huì)被識(shí)別為’ ‘或者’ '。如果不明白就復(fù)制引號(hào)中的內(nèi)容,再粘貼到word里面自然就清楚了。
2、定位缺失數(shù)據(jù)
Pandas中提供了判斷表中數(shù)據(jù)是否為缺失數(shù)據(jù)的方法isnull:
df.isnull()Unnamed: 0 First Score Second Score Third Score 0 False False False True 1 False False False False 2 False True False False 3 False False True False這里可以看到,所有NaN的位置全部變成了True。但光是這樣其實(shí)還遠(yuǎn)不夠,尤其當(dāng)數(shù)據(jù)量較大時(shí),我們其實(shí)更想的是如果準(zhǔn)確地定位這些數(shù)據(jù),再想辦法對(duì)其進(jìn)行修改。
當(dāng)然我們常規(guī)的思路是想直接定位到它的行列值上,這樣就最方便,但Pandas并沒(méi)有提供這樣的一種方法,非常可惜。于是我們只能選擇退而求其次的方案。
首先,我們可以先簡(jiǎn)單統(tǒng)計(jì)一下上哪些列有空值:
df.isnull().sum()Unnamed: 0 0 First Score 1Second Score 1Third Score 1 dtype: int64這個(gè)原理就很簡(jiǎn)單了,由于df.isnull()函數(shù)返回的表中每列全是Bool類(lèi)型,而sum()是針對(duì)數(shù)值的操作,默認(rèn)就將Ture和False轉(zhuǎn)為1和0。那么對(duì)每列數(shù)據(jù)求和自然就統(tǒng)計(jì)出了缺失的數(shù)據(jù)總量。
其次,可以考慮直接從DataFrame的值入手,獲取缺失數(shù)據(jù)在其數(shù)據(jù)主體中所在的位置。
np.argwhere(np.isnan(df.values))array([[0, 3],[2, 1],[3, 2]], dtype=int64)%timeit np.argwhere(np.isnan(df.values)) 53.8 μs ± 68.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)這里是借助Numpy中的定位函數(shù),也比較簡(jiǎn)單,運(yùn)行的時(shí)間也沒(méi)有想象中那么慢。
此時(shí)返回的數(shù)組中,第一個(gè)元素就是行數(shù),第二個(gè)元素就是列所在的位置(也從0開(kāi)始),那么也很容易找到它們對(duì)應(yīng)的列名:
for i,j in np.argwhere(np.isnan(df.values)):print('The',j,'th Column name:',df.iloc[:,j].name)The 3 th Column name: Third Score The 1 th Column name: First Score The 2 th Column name: Second Score當(dāng)然,還有更為高明的方法,可以參考Pandas缺失數(shù)據(jù)最快定位方式(極少代碼快速實(shí)現(xiàn),打死不用循環(huán)!!!)
3、修改定位數(shù)據(jù)
能夠精準(zhǔn)定位數(shù)據(jù),自然也就可以對(duì)其進(jìn)行修改了。最簡(jiǎn)單的方式自然是給出每個(gè)位置應(yīng)有的值,比如:
df.iloc[2, 1] = 32當(dāng)然,這種方式與手動(dòng)修改無(wú)異。我們想要看的是一些簡(jiǎn)單暴力而又常用的方法。
4、批量修改缺失數(shù)據(jù)
- fillna()
比如我想將所有異常數(shù)據(jù)用一種夸張的形式填充:
df.fillna("!*#^@")Unnamed: 0 First Score Second Score Third Score 0 0 100 30 !*#^@ 1 1 90 45 40 2 2 !*#^@ 56 80 3 3 95 !*#^@ 98那么自然地,也可以用一些固定的數(shù)值來(lái)填充,比如:
df.fillna(-1)Unnamed: 0 First Score Second Score Third Score 0 0 100.0 30.0 -1.0 1 1 90.0 45.0 40.0 2 2 -1.0 56.0 80.0 3 3 95.0 -1.0 98.0這里注意到,fillna()中可以填充的類(lèi)型是任意的,只要可以作為數(shù)據(jù)的東西都可以放進(jìn)去,甚至包括Pandas的object. 這里就不再贅述,其實(shí)不用看官方文檔也能很容易試出來(lái)。
- 用前或者后(同一列的上一行或下一行)的數(shù)據(jù)填充:
另外還可對(duì)填充次數(shù)進(jìn)行限制,比如只允許填充一次:
df.fillna(method='bfill',limit=1)這里由于每列數(shù)據(jù)只有一個(gè)空值,因此與上面的代碼結(jié)果無(wú)異。
5、數(shù)據(jù)修復(fù)的利器–插值法(interpolate)
可以看到上面缺失的數(shù)據(jù)都是數(shù)值,那么此時(shí)我們可以用插值的方式來(lái)處理,這種方式尤其在數(shù)據(jù)本身平穩(wěn)并且量較充足的時(shí)候非常有用。同時(shí)也很自然地想到,這種操作對(duì)于我們參加數(shù)據(jù)挖掘競(jìng)賽非常有利!
df.interpolate(method='linear')Unnamed: 0 First Score Second Score Third Score 0 0 100.0 30.0 NaN 1 1 90.0 45.0 40.0 2 2 92.5 56.0 80.0 3 3 95.0 56.0 98.0這里可以看到,多數(shù)空值都被填充了。它的原理是對(duì)現(xiàn)有的點(diǎn)進(jìn)行線(xiàn)性插值,從而達(dá)到數(shù)據(jù)填充的目的。
另外,細(xì)心的同學(xué)應(yīng)該也發(fā)現(xiàn)了,這里第一行最后一列數(shù)據(jù)并未被修改,這是因?yàn)槟J(rèn)的插值法是向前插值(即向下面的行進(jìn)行插值),那么這里稍作修改即可:
df.interpolate(method='linear',limit_direction='backward') Out[166]: Unnamed: 0 First Score Second Score Third Score 0 0 100.0 30.0 40.0 1 1 90.0 45.0 40.0 2 2 92.5 56.0 80.0 3 3 95.0 NaN 98.0如果上下都想用,就用兩次即可:
df.interpolate(method='linear',limit_direction='backward').interpolate(method='linear',limit_direction='forward')Unnamed: 0 First Score Second Score Third Score 0 0 100.0 30.0 40.0 1 1 90.0 45.0 40.0 2 2 92.5 56.0 80.0 3 3 95.0 56.0 98.0注:Pandas在實(shí)現(xiàn)這類(lèi)方法時(shí)實(shí)際上是調(diào)用的scipy的庫(kù),因此需要提前將scipy裝好。
當(dāng)然,插值的方法有很多,目前該方法提供的選擇如下:
- ‘linear’: 線(xiàn)性插值
- ‘index’, ‘values’: 用索引值直接填充.
- ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘spline’, ‘barycentric’, ‘polynomial’:
- 其中: ‘polynomial’ ,‘spline’ 需要設(shè)置階數(shù),如: df.interpolate(method='polynomial', order=5).
- ‘krogh’, ‘piecewise_polynomial’, ‘spline’, ‘pchip’, ‘a(chǎn)kima’: scipy中對(duì)應(yīng)的方法(名稱(chēng)一致)
- ‘from_derivatives’: 采用方法scipy.interpolate.BPoly.from_derivatives
關(guān)于上述所有方法的說(shuō)明可以直接參考scipy的文檔或者用戶(hù)說(shuō)明。
本系列教程教程完整目錄:
一、Pandas簡(jiǎn)介與安裝
二、Pandas基本數(shù)據(jù)結(jié)構(gòu)-DataFrame與Series
三、Pandas文件讀寫(xiě)
四、Pandas數(shù)據(jù)索引方式
五、Pandas簡(jiǎn)單統(tǒng)計(jì)操作及通用方式
六、Pandas條件查詢(xún)
七、Pandas缺失數(shù)據(jù)的處理(數(shù)據(jù)清洗基礎(chǔ))
八、Pandas數(shù)據(jù)透視表
九、表的合并、連接、拼接(數(shù)據(jù)聚合基礎(chǔ))
總結(jié)
以上是生活随笔為你收集整理的Pandas简明教程:七、Pandas缺失数据的处理(数据清洗基础)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Pandas简明教程:六、Pandas条
- 下一篇: Pandas缺失数据最快定位方式(极少代