数据小站
数据科学成长之路

浅谈python3中的编码问题

什么是编码问题

计算机,只能识别0/1这种标识。我们在网络中收到的语音、视频、图片,在计算机处理过程中,也是一串由0101组合成的字节流,计算机通过对这些0101进行分析处理后,才能让人们视觉所接受。

二进制:

计算机既然只能识别0和1,那为了表示数字,我们就用无数的0和1进行组合,来代表数字,假如我们用三个0和1来进行排列组合,可以组合成 000,001,010,011,100,101,110,111 八种组合,那我们就可以用来代表数字世界中1-8,那9代表不了怎么办,就继续增加0和1就可以了,每多增加1位0/1,就能在之前的数字基础上多扩大2倍。这也是二进制的由来。
在二进制中,每位0/1,代表一个bit,bit是最小的单位。
我们采用8个bit的二进制来表示数字,可以有0000 0000 – 1111 1111 一共有2的8次方的256个组合,就可以代表256个数字。

8个bit为1个btype(字节)。 计算机中的 1GB = 1024MB = 1024*1024 KB = 1024*1024*1024 B = 1024*1024*1024*8 bit 单位问题可以百度。

什么是编码:ASCII/ANSI/GBK编码

既然我们可以用无穷个01组合出无穷的数字,那我们就可以人为定制一套规则,每一个组合,代表我们人类语言中的一个字符。

如标准ASCII编码,采用了7bit,从000 0000 – 111 1111 一共128个组合,分别代表了数字0-9,英语小写a-z,大写A-Z,还有符号如 空格、回车、换行等等,这就满足了以英语的使用。如100 0001 代表了大写字A,110 0010代表小写字母b,当所有人都认可这一套编码之后,这个规则就可以通用了。ASCII具体编码可以参照ASCII编码表。

随着计算机在世界的普及,每个国家都有各自的语言,除了使用英文,要使用本国的语言怎么办。各国就在ascii编码的基础上,继续往前堆0/1,ascii是用1个字节表示,那各个国家就采用高位填充0,用2个字节扩充。例如ascii中的英语大写字符A,是用0100 0001表示,采用2个字节高位填充0后,就成了0000 0000 100 0001。多了一个自节后,就可以标识65536个字符,除去之前占用的256个英语字母,还有6万多字符,可以用来标识各个国家的字符。这就是ANSI编码,在中国的规则就是大名鼎鼎的GBK编码。

什么是解码

在中国,有了GBK编码之后,我们写的中文内容,就可以根据GBK的编码规则,将汉字编码成相应的二进制字节流,其他计算器拿到这个字节流之后,在根据GBK的编码规则,将字节流翻译成汉字,可以让人们读懂,这是解码。

编码问题

采用了ANSI编码之后,计算机展示各个国家的文字没有问题,造成新的问题就是各个国家之间,ANSI编码不兼容。每个国家都有自己的标准。例如在中文的GBK编码中,1101 0110 1101 0000 代表了汉字中的“中”,但是在其他国家的ANSI编码中,就对应其他国家自己语言的字符。

拿着中文编码的字符串,去给其他国家使用时,各个国家采用各自的编码规则进行解码,解码出来的内容肯定就是非人所能理解的,俗称乱码

unicode编码

为了解决数据在世界上的传输,各个国家的boss就坐到一块,一起商量,开了个会,会议达成了共识,全世界都采用一套编码规则,在这个编码里面,一个字符占用4个字节,每个国家占用其中的一块来编码各自的文字,这样兼容了世界上各个国家的所有语言。

大家都要这一套编码,这样在世界上传播的时候规则一致,都能解码,都能看懂了。

unicode编码带来的问题:

虽然unicode编码解决了世界上不同语言的兼容问题,毕竟天下没有免费的午餐。这种的编码的代价就是编码后传输的体积变大了。像只使用英语的国家,原本表示一个大写字母A只使用1个字符0100 0001就够了,在使用unicode之后,增加到了4个字符,需要向前扩充3个字符,变成了0000 0000 0000 0000 0000 0000 0100 0001才能够表示一个大写字母A。无形当中将原本的数据量,从之前的1倍,变成了4倍。对于纯使用英语字母的国度来说,无疑造成了巨大的传输浪费。白白消耗了原来4倍的带宽,然而只传输了无数个0。

UTF8编码

为了解决unicode的消耗带宽过高的问题,聪明的人们从来没有停止过思考。又想到了一个解决办法,将unicode的编码中加入前缀,有特殊的编码含义,例如unicode中的大写字母A, 0000 0000 0000 0000 0000 0000 0100 0001 ,像字母这种前三位都是0的编码,可以使用特殊的前缀,来确定后边的位数只有0100 0001,,就省去了全部有0来表示。

utf8编码规则就变成了可变长的编码…..

python3中的编码问题

在python3中,默认使用的是unicode编码。当我们输入中文字符时,在内存中是按照unicode编码存储,当需要写入硬盘时,会根据系统环境,自动按照gkb、utf8编码存储,减少存储开销。当然我们可以指定编码。

微软的win系统中,中文简体的操作系统,系统中文编码是按照ANSI编码,简体中文环境下就是GBK进行编码。

在pandas.to_csv(path,encoding=”)时,当不用encoding指定编码时,python环境是按照utf8的编码格式输出,用excel编辑打开时,会出现乱码。这是由于exce/wpsl,在win简体中文环境中遇到中文时是按照gbk的格式进行解码,而文件本身是utf8编码,就操作解码冲突,出现乱码。

pandas.to_csv(path,encoding=’ansi’) ,pandas在生成csv格式文件时,需要手工指定encoding编码类型,手动设置成ansi或者gbk,才能被excel识别。如果不知道,虽然excel识别不了,但是还是能被文本、notepad++等文本识别。因为后者是支持多种编码格式的,而简体中文格式下的excel,只能识别gbk编码。

python3编码示例:

ab = '中国'
print(ab)
print('ansi编码:',ab.encode('ansi'))
print('gbk编码',ab.encode('gbk'))
print('utf8编码',ab.encode('utf8'))
print('unicode编码',ab.encode('unicode_escape'))

中国
ansi编码:   b'\xd6\xd0\xb9\xfa'
gbk编码     b'\xd6\xd0\xb9\xfa'
utf8编码    b'\xe4\xb8\xad\xe5\x9b\xbd'
unicode编码 b'\u4e2d\u56fd'

查看“中国”的各种编码,在win的简体中文环境下, ansi和gbk的编码是一致的

相反,一串二进制,可以使用decode方式,来解码.

st = b'\xe4\xb8\xad\xe5\x9b\xbd'
print(st.decode('utf8'))   #按utf8方式解码

excel打开csv格式数据乱码问题

有时候会遇到csv格式的数据,用记事本打开可以正常,用excel或者wps打开时出现乱码。这是因为在简体中文的win系统中,excel/wps打开文件是按照gbk编码进行读取文件。当csv的文件格式是gbk时,可以正常读取,当文本是其他编码时,打开就会出现乱码。普通的文本编辑器是可以直接打开csv格式的,会根据文本的编码自动确定编码规则,可以用文本方式打开csv的数据,在转换成ansi编码,就可以用excel编辑。

赞(1) 打赏
未经允许不得转载:技术文档分享 » 浅谈python3中的编码问题

评论 抢沙发