基于pandas的数据分析之数据类型转化踩坑总结
环境依赖:
MySQL 5.7.17
Python 2.7
MySQL-python 1.2.5
pandas 0.18.1
数据类型转化从以下两个方面讨论并分析:
- 由于数据缺失导致DataFrame中int转float型
- 由于数值类型字符串导致从csv加载到DataFrame时String转numeric
一、由于数据缺失导致DataFrame中int转float型
问题描述
基于Python将MySQL的表结构转化为Pandas的DataFrame时,出现如下问题:
a)age列原本为Int类型,但是在DataFrame中转化为Float类型
b)对于SQL中的None值在DataFrame里有多种表示方式。
数据源信息如下所示:
在DataFrame中展示效果如下:
原因分析
通过查阅官方文档得知,pandas在处理缺失值上,拥有一个自己的处理及转化逻辑;具体规则描述如下图所示:
不难看出,当int型数据列包含空值时,会将该列转化为float类型;个人理解(未必一定准确):在pandas中,对于数值类型的空值,是统一用Nan来表示的;Nan在pandas中是一种特殊的float值,而非大家所熟悉的空对象;因此对于int类型的空值,因无法表示相应的空值,所以需要先做数据类型的转化,然后用Nan来表示缺失值。
通过这个例子,在理解numeric类型转化原因的同时,希望能提高对数据异常的情况的警惕性和敏感度;理解业务,实现逻辑的同时,准确有效的进行数据降噪,从而提升数据的有效性和真实性。
二、由于数值类型字符串导致从csv加载到DataFrame时String转numeric
空值分别在MySQL、Python、Pandas上的表现形式如下表所示:
/ | 字符串空值 | 空字符串 | 数值类型空值 |
---|---|---|---|
MySQL | Null | ” | Null |
Python | None | ” | None |
Pandas | None | ” | Nan |
缺失值
由于字符串空值和空字符串这两种情况在写到csv的效果完全一致,从而导致在读取数据时,无法做区分。如果后续业务明确要求区分处理这两种情况,则会因为一次读写文件的操作导致数据失真。基于此原因,建议在业务线内,规定一个唯一标识的字符串来代表None值(参考数仓建设),从而有效区分字符串空值和空字符串的区别。
数据类型转化
若某一列为数值字符串时,通过pd.read_csv方法转化为DataFrame后,该列会被识别为numeric类型(eg: int, float),而非原本的String类型。Eg:将前文中Mysql数据表中的sex列和passWord列的内容修改为纯数值,数据集及各列对应的数据类型分别如下图所示:
并将该表中的数据先写到本地csv文件;然后通过pd.read_csv读取文件数据时发现sex列被识别为int类型,passWord列被识别为float类型。数据展示效果及各列对应的数据类型分别如下图所示:
所以在基于pandas操作csv文件时,需要特别注意这种情况。如果在后续的分析中,需要保留原始数据集中的数据类型,则在读取csv文件时,需要显示的指定dtype参数,从而保证数据类型的前后统一。
通过上述案例分析,希望操作csv文件时注意空字符串和字符串空值在具体项目中的实际意义,以免造成不必要的麻烦;以及潜在的数据类型转化隐患。