发布于2026-07-13 阅读(0)
扫一扫,手机访问
内存占用虚高,是很多 Pandas 用户都会遇到的困惑。一个存着几百万行小整数的 DataFrame,用 df.info() 一看,内存占用却大得离谱,这到底是怎么回事?
根源在于 Pandas 的默认类型选择。它总是倾向于用 int64、float64 和 object 来存储数据,哪怕你存的是 0 和 1,也硬要占 8 个字节——这显然浪费。而 object 列,也就是字符串列,更是个“内存大户”,每个字符串元素都会单独分配一块内存,连引用都不共享,内存自然就上去了。你存了 10 个“Yes”,它能给你分出 10 块独立的内存空间。

df.info() 显示的内存使用远高于实际数据大小?说白了,就是默认配置的问题。Pandas 不是不聪明,它只是保守——为了确保不丢失精度,它选择了最安全、最通用的类型。比如 int64 占 8 字节,而 int8 只要 1 字节,但 Pandas 不会自动帮你做这个优化,它不知道你的数据范围。所以,看到内存虚高,别慌,这是常有的事,关键是要学会怎么给它“瘦身”。
pd.to_numeric() 和 astype() 安全降级数值类型?很多人一上来就写 df[col].astype('int32'),结果马上报错,提示 ValueError: cannot convert float NaN to integer。这就是踩坑了——int32 不支持 NaN。如果列里有缺失值,必须先处理,或者用 Pandas 提供的可空整数类型。
这里的正确做法是:
pd.to_numeric(df[col], downcast='integer') 或 downcast='float',它会自动帮你选一个最合适的小类型,比如从 int64 降到 int32,甚至 int16。NaN,那就用 Int32(注意首字母大写),这是 Pandas 专门为这种情况设计的可空类型:df[col].astype('Int32')。df[col].astype('float32'),内存直接减半,而且大多数场景下,这种精度损失完全没影响。categoryastype('category') 确实是个利器,但用不对反而会帮倒忙。它只对重复值多的字符串列有效,比如状态码、地区名这种。如果是一列 UUID 或者长文本,唯一值接近行数,用 category 反而更占内存,因为要额外维护一个映射表。
所以,在动手之前,先算一下唯一值比例:df[col].nunique() / len(df)。如果这个比例很低,比如小于 5%,那转 category 效果很好;如果比例很高,那就别费劲了,考虑其他方法。
另外,不要一股脑地把所有 object 列都批量转成 category。先用 select_dtypes('object') 筛选出来,再逐列评估。更聪明的方法是从字符串里提取关键信息。比如,如果数据是 "user_123"、"user_456" 这种格式,直接把前缀去掉,转成 uint32,效率比留字符串高得多。
dtype 和 usecols 参数等数据加载完再压缩,其实已经晚了,因为内存峰值已经产生。真正低内存的环境,必须在 pd.read_csv() 这一步就干预。
usecols 参数,只读你需要的列,别把冗余字段都载进来。dtype 参数,在读取时直接指定类型,比如 {'user_id': 'uint32', 'status': 'category', 'score': 'float32'},这样数据一进来就是压缩状态。chunksize 分块处理,每块压缩后再拼接,可以避免一次性加载爆内存。最后提醒一句:类型选错,比不压缩更糟糕。比如,把可能超范围的 ID 强制设成 uint16,后续计算会静默溢出,这种 bug 很难排查。所以,在 downcast 之前,务必核对原始数据的分布范围。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8