直奔主題:把包含中文的csv文件的編碼改成utf-8的方法:
https://stackoverflow.com/questions/191359/how-to-convert-a-file-to-utf-8-in-python
啰嗦幾句:
在用pandas讀取hive導出的csv文件時,經常會遇到類似UnicodeDecodeError: 'gbk' codec can't decode byte 0xa3 in position 12這樣的問題,這種問題是因為導出的csv文件包含中文,且這些中文的編碼不是gbk,直接用excel打開這些文件還會出現亂碼,但用記事本打開這些csv則正常顯示,然后用記事本另存為UTF-8之后,用excel打開也能夠正常顯示,並且用pandas讀取時指明encoding='utf-8'也能正常讀取了。如果讀取批量的csv時,或者csv的行數達到數百萬時,就不能通過記事本另存為來更改encoding了,那應該怎么做來保證pandas能正常讀取這些csv呢?
1.讀取時不加encoding參數,則默認使用gbk編碼來讀取數據源文件,即默認數據源文件的編碼為gbk:
import pandas as pd df=pd.read_csv(data_source_file)
2.如果源文件的中文不是gbk編碼,則可能會報錯:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa3 in position 12
那么可以試試utf-8編碼:
df=pd.read_csv(data_source_file,encoding='utf-8')
如果仍然報錯,提示utf-8也不行:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa3 in position 12
那么說明文件中的中文編碼不是utf-8,這時我們就要確定源文件的中文到底使用哪一種編碼。
3.常見的中文編碼包括:utf-8,gbk,gb2312,gb18030,cp935,big5等,我們可以逐一試過去,確定之后再修改read_csv()的encoding參數值即可。
4.如果只需要讀取一個csv文件,逐個試的方法是可行的,但是如果需要循環讀取多個csv文件,而每個csv文件的編碼都可能不一樣,那么最好還是先把所有這些csv統一轉為utf-8,再集中進行讀取,轉換文件的編碼格式需要用到python自帶的codecs模塊(見 https://stackoverflow.com/questions/191359/how-to-convert-a-file-to-utf-8-in-python),它的作用等同於我們用記事本打開再另存為utf-8編碼格式,能夠確保成功修改文件的編碼格式。其他方法,例如 Python使用三種方法批量修改記事本文件編碼格式 只是簡單的str.decode('gbk').encode('utf-8')再寫回到文件,或者 這種 都是不行的,依舊會報錯。
5. 修改csv文件為utf-8的有效代碼:
import codecs def handleEncoding(original_file,newfile): #newfile=original_file[0:original_file.rfind(.)]+'_copy.csv' f=open(original_file,'rb+') content=f.read()#讀取文件內容,content為bytes類型,而非string類型 source_encoding='utf-8' #####確定encoding類型 try: content.decode('utf-8').encode('utf-8') source_encoding='utf-8' except: try: content.decode('gbk').encode('utf-8') source_encoding='gbk' except: try: content.decode('gb2312').encode('utf-8') source_encoding='gb2312' except: try: content.decode('gb18030').encode('utf-8') source_encoding='gb18030' except: try: content.decode('big5').encode('utf-8') source_encoding='gb18030' except: content.decode('cp936').encode('utf-8') source_encoding='cp936' f.close() #####按照確定的encoding讀取文件內容,並另存為utf-8編碼: block_size=4096 with codecs.open(original_file,'r',source_encoding) as f: with codecs.open(newfile,'w','utf-8') as f2: while True: content=f.read(block_size) if not content: break f2.write(content)
把csv的中文轉換為utf-8之后,則可以用
df=pd.read(csvfile,encoding='utf-8')
來讀取。
6. 讀取文件的時候,如果編碼不對,會報decode error,需要在open(file,'r',encoding='source_file_encoding')中設置正確的encoding;
而寫文件(例如逐行讀取源文件,並把中文標點符號替換為英文標點,再另存為新文件)的時候,如果編碼不對則會報encod error(需要在
open( file,'w',encoding='targe_file_encoding')
中設置encoding,且該encoding必須和數據的來源一致(若讀取數據之后,做了encoding的轉換,則寫入的encoding必須與轉換后的encoding相同。)