Anders Wang


我所认识的每个人都是榜样,都有值得我去尊敬和学习的地方。


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中查看的有误,因为行标题丢失了,而且格式也有部分错位挤压。

1

产生这个问题的原因其实很简单,就是我们没有设置完全匹配的编码导致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  

这次输出了正常的信息,这就验证了我们之前的想法是正确的。

2

所以,当我们遇到读取数据文件编码问题的时候,就可以考虑以这样的方式去解决问题。

最近的文章

Python的魔术方法(Magic Method)

在Python中,我们时常会用到对象,而对象又包含许多方法,尤其是一些内置的方法都以"__"双下划线开头和结束,而这些方法在Python中都被统称为Magic Method,即魔术方法。 在魔术方法中…

Python, 技术博文详细阅读
更早的文章

使用Splatting方法来传递参数

转载请注明出处,不胜感激!关于PowerShell的文章,我也同步发布在我的微信公共订阅号里,欢迎关注:[一起PowerShell] 所谓一年之计在于春,一日之计在于晨,那一周之计可在于周一。上…

PowerShell, 技术博文详细阅读
comments powered by Disqus