獲取文中的
CSV
檔案用於程式碼程式設計以及文章首發地址,請點選下方超連結
在本文中,我們將使用Python
的Pandas
庫逐步完成許多不同的資料清理任務。具體而言,我們將重點關注可能是最大的資料清理任務,即 缺少值。
缺失值的來源
在深入研究程式碼之前,瞭解丟失資料的來源很重要。這是資料丟失的一些典型原因:
- 使用者忘記填寫欄位。
- 從舊版資料庫手動傳輸時,資料丟失。
- 發生程式設計錯誤。
- 使用者選擇不填寫欄位。
其中一些來源只是簡單的隨機錯誤。在其他時候,可能會有更深層的原因導致資料丟失。
準備工作
在開始清理資料集之前,最好先大致瞭解一下資料。
- 有哪些功能?
- 預期的型別是什麼(
int,float,string,boolean
)? - 是否有明顯的缺失資料(熊貓可以檢測到的值)?
- 是否還有其他型別的丟失資料不太明顯(無法通過Pandas輕鬆檢測到)?
了說明我的意思,讓我們開始研究示例。
我們要使用的資料是非常小的房地產資料集。獲取CSV
檔案。你可以單擊此處獲取,以便可以進行編碼。
快速瀏覽一下資料:
快速瞭解資料的一種好方法是檢視前幾行。在Pandas
中,你要編寫以下程式碼:
# Importing libraries
import pandas as pd
import numpy as np
# Read csv file into a pandas dataframe
df = pd.read_csv("property data.csv")
# Take a look at the first few rows
print df.head()
Out:
ST_NUM ST_NAME OWN_OCCUPIED NUM_BEDROOMS
0 104.0 PUTNAM Y 3.0
1 197.0 LEXINGTON N 3.0
2 NaN LEXINGTON N 3.0
3 201.0 BERKELEY NaN 1.0
4 203.0 BERKELEY Y 3.0
我知道我說過我們將使用Pandas
,但是可以看到我也使用了Numpy
。稍後我們將使用它來重新命名一些缺失的值。
匯入庫後,我們將csv
檔案讀取到Pandas
資料框中。
使用該方法,我們可以輕鬆看到前幾行。(使用.head()
方法)
從列名稱中推斷出以下字元組非常容易:
ST_NUM
: 街道號碼ST_NAME
: 街道名稱OWN_OCCUPIED
:住所所有人是否被佔用NUM_BEDROOMS
:臥室數
我們還可以進行設定,獲取的資料型別是啥?
ST_NUM
:float或int…某種數字型別ST_NAME
: 細繩OWN_OCCUPIED
:字串…Y(“是”)或N(“否”)NUM_BEDROOMS
:float或int,數字型別
標準缺失值
“標準缺失值”是什麼意思?這些是Pandas
可以檢測到的缺失值。
回到我們的原始資料集,讓我們看一下“ ST_NUM
”列。
第三列中有一個空單元格。在第七行中,有一個“ NA
”值。
顯然,這些都是缺失值。讓我們看看Pandas
如何處理這些問題
# 檢視ST_NUM列
print df['ST_NUM']
print df['ST_NUM'].isnull()
# 檢視ST_NUM列
Out:
0 104.0
1 197.0
2 NaN
3 201.0
4 203.0
5 207.0
6 NaN
7 213.0
8 215.0
Out:
0 False
1 False
2 True
3 False
4 False
5 False
6 True
7 False
8 False
看一下該列,我們可以看到Pandas
在空白處填充了“ NA
”。使用該方法,我們可以確認缺失值和“ NA
”都被識別為缺失值。兩個布林響應均為。isnull()
和True
這是一個簡單的示例,但強調了一個重點。Pandas
會將空單元格和“ NA
”型別都識別為缺失值。 下面,我將介紹一些Pandas
無法識別的型別。
非標準缺失值
有時可能是缺少具有不同格式的值的情況。
讓我們看一下“Number of Bedrooms
”一欄,瞭解我的意思。
在此列中,有四個缺失值。
- n/a
- NA
- —
- na
從上面中,我們知道Pandas
會將“ NA
”識別為缺失值,但其他的情況呢?讓我們來看看。
# 看NUM_BEDROOMS這一欄
print df['NUM_BEDROOMS']
print df['NUM_BEDROOMS'].isnull()
Out:
0 3
1 3
2 n/a
3 1
4 3
5 NaN
6 2
7 --
8 na
Out:
0 False
1 False
2 False
3 False
4 False
5 True
6 False
7 False
8 False
就像以前一樣,Pandas
認為“ NA
”是缺失的價值。不幸的是,其他型別未被識別。
如果有多個使用者手動輸入資料,則這是一個常見問題。也許我喜歡使用“ n / a
”,但是其他人喜歡使用“ na
”。
檢測這些各種格式的一種簡單方法是將它們放在列表中。然後,當我們匯入資料時,Pandas
會立即識別出它們。這是我們將如何執行此操作的示例。
# 列出缺失的值型別
missing_values = ["n/a", "na", "--"]
df = pd.read_csv("property data.csv", na_values = missing_values)
現在,讓我們再看一下該欄,看看會發生什麼。
# 看NUM_BEDROOMS這一欄
print df['NUM_BEDROOMS']
print df['NUM_BEDROOMS'].isnull()
Out:
0 3.0
1 3.0
2 NaN
3 1.0
4 3.0
5 NaN
6 2.0
7 NaN
8 NaN
Out:
0 False
1 False
2 True
3 False
4 False
5 True
6 False
7 True
8 True
下面中,我們將介紹一種更復雜但很常見的缺失值型別。
意外的缺失值
到目前為止,我們已經看到了標準缺失值和非標準缺失值。如果我們出現意外型別怎麼辦?
例如,如果我們的功能應該是字串,但是有數字型別,那麼從技術上講,這也是一個缺失值。
讓我們看一下“Owner Occupied
**”一欄,看看我在說什麼。
從前面的示例中,我們知道Pandas
將檢測到第7行中的空單元格為缺失值。讓我們用一些程式碼進行確認。
# 檢視OWN_OCCUPIED列
print df['OWN_OCCUPIED']
print df['OWN_OCCUPIED'].isnull()
# 檢視OWN_OCCUPIED列
Out:
0 Y
1 N
2 N
3 12
4 Y
5 Y
6 NaN
7 Y
8 Y
Out:
0 False
1 False
2 False
3 False
4 False
5 False
6 True
7 False
8 False
在第四行中,數字為12。Owner Occupied
的響應顯然應該是字串(Y或N)
,因此此數字型別應為缺失值。
這個示例稍微複雜一點,因此我們需要考慮一種策略來檢測這些型別的缺失值。有很多不同的方法,但是這是我要通過這種方法工作的方式。
- 遍歷OWN_OCCUPIED列
- 嘗試將條目轉換為整數
- 如果條目可以更改為整數,請輸入缺失值
- 如果數字不能是整數,我們知道它是一個字串,所以繼續
看一下程式碼,然後我將對其進行詳細介紹
# 檢測資料
cnt=0
for row in df['OWN_OCCUPIED']:
try:
int(row)
df.loc[cnt, 'OWN_OCCUPIED']=np.nan
except ValueError:
pass
cnt+=1
在程式碼中,我們迴圈瀏覽“所有者已佔用”列中的每個條目。要嘗試將條目更改為整數,我們使用。int(row)
如果可以將值更改為整數,則可以使用Numpy's
將條目更改為缺少的值。np.nan
另一方面,如果不能將其更改為整數,我們pass
將繼續。
您會注意到我使用try
和except ValueError
。這稱為異常處理,我們使用它來處理錯誤。
如果我們嘗試將一個條目更改為一個整數並且無法更改,則將ValueError返回a
,並且程式碼將停止。為了解決這個問題,我們使用異常處理來識別這些錯誤,並繼續進行下去。
程式碼的另一個重要部分是.loc
方法。這是用於修改現有條目的首選Pandas方法。有關此的更多資訊,請檢視Pandas
文件。
現在,我們已經研究了檢測缺失值的不同方法,下面將概述和替換它們。
總結缺失值
清除缺失的值後,我們可能要對它們進行彙總。例如,我們可能要檢視每個功能的缺失值總數。
# Total missing values for each feature
print df.isnull().sum()
Out:
ST_NUM 2
ST_NAME 0
OWN_OCCUPIED 2
NUM_BEDROOMS 4
在更多的時候,我們可能需要進行快速檢查,以檢視是否根本缺少任何值。
# Any missing values?
print df.isnull().values.any()
Out:
True
我們可能還希望獲得缺失值的總數。
# Total number of missing values
print df.isnull().sum().sum()
Out:
8
在上面,我們總結了缺失值的數量,讓我們看一下如何進行一些簡單的替換。
更換
通常,您必須弄清楚如何處理缺失值。
有時,您只是想刪除這些行,而其他時候,您將替換它們。
正如我之前提到的,這不應該掉以輕心。我們將介紹一些基本的推論。
# 用一個數字替換缺失的值
df['ST_NUM'].fillna(125, inplace=True)
如果進行基於位置的插補。
# 基於位置的更換
df.loc[2,'ST_NUM'] = 125
替換缺失值的一種非常常見的方法是使用中位數。
# 取代使用中位數
median = df['NUM_BEDROOMS'].median()
df['NUM_BEDROOMS'].fillna(median, inplace=True)