pandas read_csv mixed types问题

一、问题的缘起

用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问题了。
但是这种方式真的非常不好,一旦csv文件过大,就会内存溢出;所以推荐用第1中解决方案。

pandas官方文档对low_memory说明:
low_memory : boolean, default True
Internally process the file in chunks, resulting in lower memory use while parsing, but possibly mixed type inference. To ensure no mixed types either set False, or specify the type with the dtype parameter. Note that the entire file is read into a single DataFrame regardless, use the chunksize or iterator parameter to return the data in chunks. (Only valid with C parser)