pandas讀取中文檔案的UnicodeDecodeError編碼問題彙總
Outline
- 批量處理檔案
- 獲取檔案編碼
- 不能decode bytes …
- python的異常處理
- read_csv中的error_bad_line引數
- 小感
批量處理檔案
為了批量處理檔案,當然是想辦法獲取檔名,通過檔名形成檔案路徑從而批處理檔案。
我以前繞過大彎,根據檔案的命名規律,尤其是其中的數字遞增規律來建立路徑,自從發現os庫裡的listdir函式才知道自己有多蠢!
獲取資料夾下所有檔案的filename
files = os.listdir(r'C:\Users\didi\Desktop\work\perf\perform_1')
files是perform_1資料夾下所有檔案的檔名形成的列表,再迴圈處理
all_data = []
for file in files:
file_path = 'C:/Users/didi/Desktop/work/perf/perform_1/' + file
encoding = get_encoding(file_path)
print(encoding)
f = open(file_path,encoding=encoding,errors='ignore')
new_data = []
for line in f.readlines():
# each_line = line.replace('\n','').split(',')
new_data.append(line)
new_data = new_data[1:]
for i in new_data:
all_data.append(i)
print(all_data)
獲取檔案編碼
# 獲取檔案編碼型別
def get_encoding(file):
# 二進位制方式讀取,獲取位元組資料,檢測型別
with open(file, 'rb') as f:
return chardet.detect(f.read())['encoding']
不能decode bytes …
原因:有些編碼是不相容的,比如utf-8不能gbk的,GB2312不能解碼GBK中的有些字元,我們需要知道檔案本身的編碼是什麼
解決辦法:
1、我們用上一個<獲取檔案編碼>裡的方法得到檔案的編碼,然後在open函式中設定encoding引數為檔案自身的編碼
encoding = get_encoding(file_path)
f = open(file_path,encoding=encoding)
2、對於中文字元的問題,我們已知底下的排序,按照編碼方式包含的字元數的多少從少到多進行排序。因為GB2312編碼的,我們可以試圖用GBK或者更高的GB18030來開啟。
GB2312 < GBK < GB18030
3、如果繼續出現UnicodeDecodeError問題,則可以設定open函式中的error引數來控制錯誤的策略。
預設的引數就是strict,代表遇到非法字元時丟擲異常; 如果設定為ignore,則會忽略非法字元; 如果設定為replace,則會用?取代非法字元; 如果設定為xmlcharrefreplace,則使用XML的字元引用
因此最終我是這麼解決我的問題的:
df = pd.DataFrame()
files = os.listdir('intern/perform/')
for file in files:
file_path = 'perform/' + file
encoding = get_encoding(file_path) # get_encoding函式在上文
f = open(file_path, encoding=encoding,errors='replace')
data = pd.read_csv(f, skiprows=1, header=None)
df = df.append(data)
想設定成replace是因為我想知道未解碼成功的字元在哪些位置,當然也可以選擇ignore進行處理
python的異常處理
read_csv中的error_bad_line引數
發覺read_csv中有用的引數真的特別多,skiprows header sep parse_dates等等等等
而今天發現的error_bad_line引數是當你遇到特別異常的記錄時,比如某一行的逗號較其他行多,導致資料的列數不匹配,這會引起異常,也不會返回相應的dataframe。而如果設定error_bad_line = False,可以選擇返回的dataframe裡面捨棄掉“bad_line”
而另一個與之相匹配的引數是warn_bad_lines,通過True or False選擇是否提示跳過的line
data = pd.read_csv(f, skiprows=1, header=None,error_bad_lines = False,warn_bad_lines=True)
小感
實際問題場景中,資料遠比我們的想象的要髒很多,各種亂七八糟的想象不到的問題,而你眼中所見的也會迷惑你,不管怎樣,兵來將擋水來土掩,養成良好的獨立搜尋解決問題的習慣,形成自己的知識結構以及對資料的敏感度和處理經驗,是最重要的~