Python读取数据编码排错
在Python开发中,当需要读取某些数据文件或者获取某些数据时,很有可能会遇到因为编码不匹配而报错的情况。这类问题其实非常常见,主要原因,还是因为没有选择正确的编码来识别所导致的。
为了很好的说明并解决这个问题,我以一个实际场景为例。当前,有一个csv格式的excel数据文件,为了确保数据文件的编码与我们假设的一致,我手动打开将此csv文件并明确以UTF-8编码另存为再次保存了一遍,默认情况下这个文件理应当以UTF-8的编码格式保存了。
下面简单的使用pandas库并以显式地方式设置以UTF-8的编码格式去读取csv文件,然后把最终数据赋值给data1并输出看看结果。
import pandas as pd
data1 = pd.read_csv('/Users/Anders/Downloads/dataset.csv', engine='python', encoding='UTF-8')
data1
运气好的是,并没有出现编码报错问题,但是仔细查看,发现输出的信息明显与我们在excel中查看的有误,因为行标题丢失了,而且格式也有部分错位挤压。
产生这个问题的原因其实很简单,就是我们没有设置完全匹配的编码导致Python读不懂,只能返回错误的数据或者甚至是报错信息。
解决的办法也十分简单,自然是想办法去查看文件真正的编码到底是什么,然后再以正确的编码格式去读取csv文件。那么对于如何获取文件的真正编码格式,我们需要用到一个第三方库名为chardet,可以用它来检测编码。在安装完该库后,我们可以很简单的用它来做各种编码检测,举个例子如下:
import chardet
data = '这是一个例子'.encode('GBK')
chardet.detect(data)
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
这里的encoding代表了检测的编码类型,confidence代表了正确的识别率,language代表了识别的语言。但是我们看到这里显示的是编码是GB2312,为什么不是之前我们设置的GBK呢?
原因是这样的,对于中文字符的问题,实际有如下已知入下的排序,按照编码方式包含的字符数的多少从少到多进行排序。假设我们的文件是以GB2312编码的,那我们可以试图用GBK或者更高的GB18030来打开。
GB2312 < GBK < GB18030
这就是为什么之前我们设置了GBK而实际显示了GB2312,后者是前者的一个兼容子集关系。
现在,知道了如何获取数据编码的格式后,我们就编写如下方法检查要打开的文件是什么编码,虽然你保存csv的时候保存了指定的编码,比如保存的时候是【逗号分隔符csv utf-8】类型,但是可能实际的编码是UTF-8 GIS编码,那么打开也是有问题的。
import chardet
# 获取文件编码类型
def get_encoding(file):
# 二进制方式读取,获取字节数据,检测类型
with open(file, 'rb') as f:
return chardet.detect(f.read())['encoding']
get_encoding('/Users/Anders/Downloads/dataset.csv')
最后实际发现输出的编码结果是UTF-8-SIG, 这也就是为什么我们使用UTF-8没有获得正常的输出信息的原因。现在我们把实际编码改为UTF-8-SIG再次看下。
import pandas as pd
data1 = pd.read_csv('/Users/Anders/Downloads/dataset.csv', engine='python', encoding='UTF-8')
data1
这次输出了正常的信息,这就验证了我们之前的想法是正确的。
所以,当我们遇到读取数据文件编码问题的时候,就可以考虑以这样的方式去解决问题。