
人生苦短,我用 Python
前文傳送門:
小白學 Python 資料分析(1):資料分析基礎
小白學 Python 資料分析(2):Pandas (一)概述
小白學 Python 資料分析(3):Pandas (二)資料結構 Series
小白學 Python 資料分析(4):Pandas (三)資料結構 DataFrame
小白學 Python 資料分析(5):Pandas (四)基礎操作(1)檢視資料
小白學 Python 資料分析(6):Pandas (五)基礎操作(2)資料選擇
小白學 Python 資料分析(7):Pandas (六)資料導入
引言
上一篇我們介紹了資料導入,在進行分析之前,還有一個比較重要的步驟就是資料的預處理,很多時候,我們導入的資料品質并不高,會有很多不達标的資料。
這就和我們每天做飯是一樣的,買回來的菜總歸會有一些不太好的部分,我們需要在做飯之前對這些菜做一些預處理,将不好的部分處理掉。
常見的資料問題主要有缺失資料、重複資料以及異常資料這麼幾種,在開始進行資料分析之前,我們需要先把這部分的資料處理掉。
缺失資料處理
缺失資料其實就是由于某些不為人知的原因導緻的部分資料為空,關注點不要放在不為人知的原因是啥上哈,這種原因簡直多了去了,任何一位程式員都能舉出來無數種例子。
對于這種部分為空的資料我們通常有兩種處理方式,一種是直接删除,還有一種是填充某種設定值。
當然,選用哪種方式完全是看具體的業務場景。
首先,第一步當然是把缺失的資料找出來, Pandas 找缺失資料可以使用
info()
這個方法(這裡選用的資料源還是前面一篇文章所使用的 Excel ,小編這裡簡單的随機删除掉幾個資料):
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df)
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
1 juejin NaN 0 -2.0 1 2019-11-23 23:00:03
2 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
3 cnblog 650.0 3 NaN 0 2019-11-22 23:00:15
4 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
.. ... ... ... ... ... ...
403 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
404 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
405 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
406 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
407 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[408 rows x 6 columns]
print(df.info())
# 輸出結果
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 408 entries, 0 to 407
Data columns (total 6 columns):
plantform 408 non-null object
read_num 406 non-null float64
fans_num 408 non-null int64
rank_num 407 non-null float64
like_num 408 non-null int64
create_date 408 non-null datetime64[ns]
dtypes: datetime64[ns](1), float64(2), int64(2), object(1)
memory usage: 19.2+ KB
從結果中可以看到,不為空的行數共計 408 行,而
read_num
這一行為 406 ,說明小編在這一列删掉了 2 個資料,在
rank_num
這一列删掉了 1 個資料。
我們還可以使用另一個更加直覺的方式來擷取缺失的資料
isnull()
,如果是缺失的值,會傳回 True ,如果不是則會傳回 False :
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.isnull())
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 False False False False False False
1 False True False False False False
2 False False False False False False
3 False False False True False False
4 False False False False False False
.. ... ... ... ... ... ...
403 False False False False False False
404 False False False False False False
405 False False False False False False
406 False False False False False False
407 False False False False False False
[408 rows x 6 columns]
使用
isnull()
是比較直覺,那麼這裡存在一個問題,就是好像資料顯示不全啊,這種問題小 case ,隻需一行代碼輕松解決:
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
pd.set_option('display.max_rows', None)
print(df.isnull())
隻需要對 pd 的顯示設定下最大行數就好,結果稍微有點長,小編就不貼了。
缺失資料删除
我們找到了缺失的資料,接下來就是對這部分資料進行删除操作了, Pandas 同樣為我們提供了一個現成的方法
dropna()
。
dropna()
這個方法會預設删除缺失資料的行,就是這一行隻要有缺失資料,整行都會删除:
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.dropna())
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
2 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
4 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
5 csdn 2202.0 129 0.0 37 2019-11-22 23:00:01
7 csdn 1621.0 76 0.0 27 2019-11-21 23:00:02
.. ... ... ... ... ... ...
403 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
404 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
405 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
406 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
407 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[405 rows x 6 columns]
可以看到,這裡顯示的行數隻剩 405 行了,其中有 3 行有缺失的資料已經删除了。
在删除缺失行的時候還會有一種情況,就是整行資料全都缺失,我們還可以隻删除整行資料全缺失,如果隻是有缺失值的資料保留,這時我們可以用到
dropna()
的一個參數
how="any"
:
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.dropna(how="any"))
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
1 juejin NaN 0 -2.0 1 2019-11-23 23:00:03
2 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
3 cnblog 650.0 3 NaN 0 2019-11-22 23:00:15
4 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
.. ... ... ... ... ... ...
403 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
404 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
405 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
406 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
407 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[408 rows x 6 columns]
因為小編的資料沒有整行缺失的,可以看到這裡又列印了所有的資料。
當然,
dropna()
同時支援各種條件删除,這裡篇幅原因小編就不一一列舉了,有需要的同學可以通路官方文檔檢視:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html 。
缺失資料填充
前面我們介紹了缺失資料的删除,但是資料是很寶貴的,通常情況下肯定不能做簡單的删除操作,更多的時候我們是希望能填充我們想要的預設值,這裡我們可以用到
fillna()
這個方法。
例如我們在剛才的資料中補充 0 :
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.fillna(0))
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
1 juejin 0.0 0 -2.0 1 2019-11-23 23:00:03
2 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
3 cnblog 650.0 3 0.0 0 2019-11-22 23:00:15
4 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
.. ... ... ... ... ... ...
403 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
404 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
405 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
406 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
407 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[408 rows x 6 columns]
上面的示例是将所有的缺失資料全都填充成了 0 ,但是如果我們隻想填充其中的一列資料呢?
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.fillna({'read_num': 10}))
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
1 juejin 10.0 0 -2.0 1 2019-11-23 23:00:03
2 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
3 cnblog 650.0 3 NaN 0 2019-11-22 23:00:15
4 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
.. ... ... ... ... ... ...
403 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
404 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
405 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
406 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
407 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[408 rows x 6 columns]
為了便于區分,小編這裡隻補充了
read_num
這一列,将預設填充數值補充成了 10 。
重複資料處理
重複資料是指相同的記錄有多條,這裡一般簡單的做删除操作。
Pandas 為我們提供了
drop_duplicates()
方法用作重複值處理,預設會對所有值進行判斷,并且會預設保留第一個值。
為了示範,小編将 Excel 中的資料第一行複制了一條。
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df)
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
1 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
2 juejin NaN 0 -2.0 1 2019-11-23 23:00:03
3 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
4 cnblog 650.0 3 NaN 0 2019-11-22 23:00:15
.. ... ... ... ... ... ...
404 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
405 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
406 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
407 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
408 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[409 rows x 6 columns]
print(df.drop_duplicates())
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
2 juejin NaN 0 -2.0 1 2019-11-23 23:00:03
3 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
4 cnblog 650.0 3 NaN 0 2019-11-22 23:00:15
5 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
.. ... ... ... ... ... ...
404 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
405 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
406 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
407 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
408 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[408 rows x 6 columns]
可以看到第一個示例中共有 409 行資料,到了第二個結果,就隻剩 408 行資料了。
這個示例是針對整體值進行判斷的,我們同樣可以隻針對某一列進行去重,隻需要在
drop_duplicates()
這個方法中指明要判斷的列即可:
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.drop_duplicates(subset='read_num'))
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
0 cnblog 215.0 0 118.0 0 2019-11-23 23:00:10
2 juejin NaN 0 -2.0 1 2019-11-23 23:00:03
3 csdn 1652.0 69 0.0 24 2019-11-23 23:00:02
4 cnblog 650.0 3 NaN 0 2019-11-22 23:00:15
5 juejin 272.0 3 -23.0 1 2019-11-22 23:00:02
.. ... ... ... ... ... ...
403 cnblog 140.0 0 37.0 0 2020-02-20 23:00:08
404 juejin 212.0 0 -1.0 2 2020-02-20 23:00:02
405 csdn 1602.0 1 0.0 1 2020-02-20 23:00:01
406 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
408 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
[342 rows x 6 columns]
可以看到這裡隻剩下了 342 行記錄,當然對不對小編沒有區驗證,這個可以通過 sql 直接在資料庫中做查詢驗證或者在 Excel 中使用去重進行驗證(小編相信官方的 API 不會騙人)。
除了這些,還可以自定義删除重複項時保留哪個,預設是保留第一個,也可以設定保留最後一個,還可以設定一個都不保留:
import pandas as pd
# 相對路徑
df = pd.read_excel("result_data.xlsx")
print(df.drop_duplicates(subset='plantform', keep='last'))
# 輸出結果
plantform read_num fans_num rank_num like_num create_date
406 cnblog 19.0 0 41.0 0 2020-02-21 23:00:05
407 juejin 125.0 1 -4.0 0 2020-02-21 23:00:02
408 csdn 1475.0 8 0.0 3 2020-02-21 23:00:02
小編這裡選擇通過
plantform
字段進行去重篩選,從行号上看應該對的,保留了最後三條資料。
keep
的值預設是
first
,也就是隻保留第一個,除了
first
,
last
還有一個是 False ,它的含義是一個都不保留。
本篇的内容就到這裡結束了,希望各位同學能多動動手,多敲敲代碼,雖然這是學代碼最笨的辦法,但同時也是最有效的方法。
示例代碼
老規矩,所有的示例代碼都會上傳至代碼管理倉庫 Github 和 Gitee 上,友善大家取用。
示例代碼-Github
示例代碼-Gitee
掃描二維碼關注「極客挖掘機」公衆号!作者:極客挖掘機
定期發表作者的思考:技術、産品、營運、自我提升等。
本文版權歸作者極客挖掘機和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
如果您覺得作者的文章對您有幫助,就來作者個人小站逛逛吧:
極客挖掘機