1. 程式人生 > >python檔案的編碼和解碼以及chardet模組使用

python檔案的編碼和解碼以及chardet模組使用

繼上一篇文章後的一次比賽心得。

其一:做個學習的資料記錄。其二:分享出來,供大家參考。

這是關於 檔案進行編碼處理後同過python解碼認知的問題。

首先我們應該知道æ–‡å—化ã??、����������等都是需要使用編碼才能解讀的字元,如果不使用正確的編碼格式,那麼始終無法進行字元的解讀。我們看一個例子:

before = "I'd recommend $, #, 你好 and नमस्ते"        #這是一串字元包括了許多的型別
after = before.encode("utf-8",errors="replace")        #我們對其進行utf-8的編碼處理,並使用錯誤處理代替
print(after)   
b"I'd recommend $, #, \xe4\xbd\xa0\xe5\xa5\xbd and \xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87"

以上的輸出結果我們可以看到使用了正確的編碼後的輸出結果。

before = "I'd recommend $, #, 你好 and नमस्ते"
after = before.encode("ascii",errors="replace")    #換成ascii來進行編碼
print(after)
b"I'd recommend $, #, ?? and ??????"

可以看出我們使用了錯誤的編碼格式,導致了?的出現。

before = "I'd recommend $, #, 你好 and नमस्ते"
after = before.encode("utf-8",errors="replace")
after = after.decode("utf-8")    #這裡我們使用decode進行utf-8格式的解碼
print(after)
#I'd recommend $, #, 你好 and नमस्ते    #獲取到了正確的格式

但是如果你使用ascii來解碼將會出現錯誤提示。

utf-8是一種極為普遍的編碼格式,對於python來說它的所用程式碼都是使用utf-8來編碼的,這是個好訊息。

重點說一下大資料的編碼問題,通常我們使用直接讀取檔案來獲得內容,但是有的時候檔案存在編碼問題,所以我們需要使用正確的編碼格式來開啟檔案。但是檔案的編碼格式我們不知道,這是chatdet則可以幫助我們有效的解決問題,如下:

data = pd.read_csv("police.csv")

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 2: invalid start byte

提示錯誤,預設的utf-8不能解碼。這該如何是好,之時就可以使用chardet模組了:

import chardet
with open("PoliceKillingsUS.csv","rb") as k:
	dd = chardet.detect(k.read(10000))

{'encoding': 'ascii', 'confidence': 1, 'language': ''}    從輸出我們可以看出這個模組有1的概率認為這是windows-1252的編碼格式
所以我們可以使用這個格式來試試

UnicodeDecodeError: 'ascii' codec can't decode byte 0x96 in position 2: ordinal not in range(128)    #我去竟然錯誤了,這個模組什麼鬼

不急,這裡真是我想說的,其實我們k.read(10000),檔案已經讀取了很多資料了,但是它還是判斷錯了。其實在大多數的小資料中它是可以判斷正確的,這是這裡資料量太大了,所以我們改為k.read(100000):

{'encoding': 'Windows-1252', 'confidence': 0.73, 'language': ''}

這下可以看出來,在讀了做了大量的判斷後它認為有0.73是windows-1252格式的編碼,所以我們再試試。

data = pd.read_csv("PoliceKillingsUS.csv",encoding="Windows-1252")
print(data.head(5))
   id                name      date   manner_of_death       armed   age  \
0   3          Tim Elliot  02/01/15              shot         gun  53.0
1   4    Lewis Lee Lembke  02/01/15              shot         gun  47.0
2   5  John Paul Quintero  03/01/15  shot and Tasered     unarmed  23.0
3   8     Matthew Hoffman  04/01/15              shot  toy weapon  32.0
4   9   Michael Rodriguez  04/01/15              shot    nail gun  39.0

  gender race           city state  signs_of_mental_illness threat_level  \
0      M    A        Shelton    WA                     True       attack
1      M    W          Aloha    OR                    False       attack
2      M    H        Wichita    KS                    False        other
3      M    W  San Francisco    CA                     True       attack
4      M    H          Evans    CO                    False       attack

          flee  body_camera
0  Not fleeing        False
1  Not fleeing        False
2  Not fleeing        False
3  Not fleeing        False
4  Not fleeing        False
可以看出是沒有問題的,所以在讀取檔案是有效的利用chardet模組,能解決大量的編碼問題。以上的k.read(100000)增大資料量只是一種方式。下面還有一種相對比較複雜的方法,但更高階。

from chardet.universaldetector import UniversalDetector

usock = open("PoliceKillingsUS.csv", 'rb')
detector = UniversalDetector()
for line in usock.readlines():
    detector.feed(line)
    if detector.done: break
detector.close()
usock.close()
print (detector.result)
{'encoding': 'Windows-1252', 'confidence': 0.73, 'language': ''}

這種相對複雜當更高階的方法也可以做出辨認。

最後就是我們可以將我們轉換編碼後的文字進行儲存,這個比較簡單:

pd.to_csv("PoliceKillingsUS_utf-8.csv")

OK以上是這次比賽的一部分的收穫!