为何修改Pandas数据类型存为CSV后,类型恢复且文件未缩小?
问题分析与解决方案
这其实是CSV格式的固有局限性导致的,不是你的操作出错了,咱们一步步理清楚:
为什么存成CSV后文件大小没变化?
CSV是纯文本格式,它不存储任何数据类型的元信息——也就是说,当你把category类型的列写入CSV时,Pandas会自动把这些分类的实际字符串值写入文件,和原来object类型的列写入的内容完全一样,所以文件大小自然不会减小。
为什么重新导入后数据类型恢复、内存占用上升?
当你用pd.read_csv()读取文件时,Pandas默认会自动推断列的数据类型:对于字符串内容的列,它会默认识别为object类型(而不是category)。object类型存储每个字符串的独立引用,内存开销远大于category类型(尤其是当列中有大量重复值时),所以内存占用又回到了原来的水平甚至更高。
解决办法
根据你的需求,有两种可行的方案:
方案1:使用支持元数据存储的二进制格式(推荐)
如果不需要用CSV这种纯文本格式,建议用Pandas支持的二进制格式来保存数据,这些格式会同时存储数据和类型信息:
- Pickle:Pandas原生格式,保存和读取都很方便:
# 保存 test.to_pickle('test.pkl') # 读取,会自动保留category类型 df = pd.read_pickle('test.pkl') - Parquet:更高效的列式存储格式,支持压缩和跨语言读取,内存占用更低:
# 需要先安装pyarrow或fastparquet # pip install pyarrow test.to_parquet('test.parquet') # 读取 df = pd.read_parquet('test.parquet')
用这些格式保存后,文件大小会明显减小,而且读取后直接保留category类型,内存占用和之前优化后的一致。
方案2:必须用CSV时,手动指定数据类型读取
如果一定要用CSV格式,那在读取的时候手动指定列的类型,避免Pandas自动推断:
df = pd.read_csv("test.csv", dtype={ "CUSTOMER_ID": "category", "SIGNAL_NAME": "category", "SIGNAL_DESCRIPTION": "category" })
这样读取后,这些列会直接是category类型,内存占用会回到95MB左右。
内容的提问来源于stack exchange,提问作者Moritz
相关产品推荐
相关产品推荐

