一、问题的缘起
用pandas读csv,通过某些条件来清洗数据;感觉清洗出来的数据不对,就又用Python自带的csv模块进行了一次清洗;发现两种方式清洗出来的数据结果不一致,决定一探究竟。
二、首先注意到pandas的警告
DtypeWarning: Columns (1,5,7,16,......) have mixed types. Specify dtype option on import or set low_memory=False.
意思就是:列1,5,7,16....的数据类型不一样。
调试进去看了看,发现pandas在读取的时候确实把同一列数据中同一
个数值识别为不同的类型,比如:2000行第3列值为0的数据识别为Int类型,
而在4000行第3列值为0的数据识别为str类型。
解决这个问题有两个方案:
# 1.设置read_csv的dtype参数,指定字段的数据类型
pd.read_csv(sio, dtype={"user_id": int, "username": object})
# 2.设置read_csv的low_memory参数为False
pd.read_csv(sio, low_memory=False})
笔者开始遇到的用pandas和csv模块清洗数据的结果不一致问题,就是因为pandas对某些字段的数据类型进行猜测时几次猜测结果不一致造成。
三、low_memory是怎么解决问题的?
pandas读取csv文件默认是按块读取的,即不一次性全部读取;
另外pandas对数据的类型是完全靠猜的,所以pandas每读取一块数据就对csv字段的数据类型进行猜一次,所以有可能pandas在读取不同块时对同一字段的数据类型猜测结果不一致。
low_memory=False 参数设置后,pandas会一次性读取csv中的所有数据,然后对字段的数据类型进行唯一的一次猜测。这样就不会导致同一字段的Mixed types问题了。