數據不正確(格式不正確,數據不准確,數據缺失)我們做什么都是徒勞。數據清洗時數據分析的第一步,也是最耗時的一步。
數據清洗很枯燥,但是隨着數據清理技巧越來越熟練,就有越有可能從他人無從下手的文檔中獲取更多的有用信息。
這次想說一下,看起來都是正確的數值數據,在人和機器理解起來的差別
Pandas 加載數據后, head() 預覽一下,感覺數據還不錯,但是,很有可能是被數據的表象所蒙蔽了。
在 Python 中,2 是一個數字,“2”是一個字符。他們是不同的數據類型,但是,都可以進行數學計算。示例如下:

如果剛開始接觸 Python 的人會有些疑惑,這是什么鬼,是不是例子處理意外。
“2”* 2 => 22
2 * 2 => 4
不僅僅是 *,在 Python 中 + 也一樣,只要他們操作的兩邊數據類型一致就可以運算。
注意,要是將一個字符串數字和一個數值數字相加,就會出現異常“TypeError: must be str, not int”

“*” 和 “*” 操作很靈活,只要理解這些行為,似乎也不是個問題。這樣問題的產生主要是語言設計者所決定的,他們只是沒有把字符串的拼接和數值相加使用了同樣的操作符。
下面就造一些數據,在 DataFrame 中看起來都像是數值類型數字的數據。

從輸出來看,都是數值類型的數據,接下來,我們做一些簡單的數據分析。假設需求,將所有的數值增大十倍。

似乎結果和最初設想的有所差距。
Data2 行的數據看上去想數值,但是,就結果來看,也不像是數值。現在我們最迫切需要知道的每列數據的類型是什么,Pandas 已經提供了查看 DataFrame 各個列數據類型的屬性。

怎么回事,都是 object 類型,Pandas 並沒有承認這些數據是數值類型。所以,開始數據分析之前,做數據清洗還是有必要的。Pandas 提供了轉換數值類型的方法,to_numeric()。
我們現在嘗試將 Data2 行的數據轉換成數值類型

轉換失敗,to_numeric() 不能將字符串 “F”轉換為數值類型,我們也沒有在代碼中控制,所以拋異常了。Pandas 提供了一個可選的參數 errors,傳入 errors='coerce' Pandas 遇到不能轉換的數據就會賦值為 NaN(Not a Number)

從結果來看,好像這次除了 “F”是空值外,其他的數據都轉換了對應的數值。我們再次執行翻十倍的運行算

下面我們再次查看一下數據的類型。

現在數據和我們設想的一樣了。
這幾次的博客都涉及了 lambda 的使用,如果有同學需要我提供一個 lambda 相關的文章,請留言,以便我規划一下時間。
整合代碼
# 演示數字和字符串的區別 two_char = '2' two_num = 2 def doubule(x): return x * 2 print('char:{}'.format(doubule(two_char))) print('num:{}'.format(doubule(two_num))) print('text:{}'.format(doubule('Test text end '))) # 報錯,類型不對 print("2" + 2) # 模擬數據 import pandas as pd df = pd.DataFrame([[1,2,3,4,16],['1','2','3','4','F']],index =['Data1','Data2']) print(df) # 翻十倍,查看結果與預想結果的差別 df.apply(lambda x: x * 10) # 查看數據類型 df.dtypes # 嘗試轉換,報錯 df.loc['Data2'] = pd.to_numeric(df.loc['Data2']) # 只轉換能轉換的,不能轉換的賦值為 NaN(Not a Number) df.loc['Data2'] = pd.to_numeric(df.loc['Data2'] ,errors='coerce') # 查看成功轉換后的結果 df.loc['Data2'] # 再次運算,查看結果與預想結果的差別 df = df.apply(lambda x: x * 10) print(df) # 查看數據類型 df.dtypes
更多關於數據清洗的內容可以關注知乎上的專欄“數據清洗”