memory_usage(deep=true)是定位真实内存占用的唯一可靠方法,因deep=false仅统计指针大小而严重低估object列内存;需显式启用deep=true并配合单位换算与索引控制进行精准诊断。

memory_usage 不是用来“估算”内存的,它是你唯一能快速定位真实内存黑洞的入口。默认不加参数时,它几乎没用——尤其当你有 object 列时,返回值严重低估实际占用。
为什么默认 deep=False 会误导你
默认情况下 memory_usage(deep=False) 只统计指针大小(8 字节/元素),完全忽略字符串、列表、字典等 Python 对象本身的内存。比如一列百万级 object 字符串,deep=False 可能只报 8MB,实际可能占 60MB+。
常见错误现象:DataFrame 明明只读了 200MB 的 CSV,却吃掉 1.2GB 内存,df.info() 却显示 “memory usage: 210.4 MB”。这就是 deep=False 在撒谎。
- 必须显式传
deep=True才能触发对象内容级扫描 -
deep=True有性能代价:对大object列(如长文本)可能卡顿几秒 - 不是所有场景都需要
deep=True—— 数值列为主时,deep=False已足够准
memory_usage 和 info() 的关键区别
df.info() 默认调用的就是 memory_usage(deep=False),且无法关闭对象内存的隐藏逻辑。而 df.memory_usage(deep=True) 是你手动打开真相开关的唯一方式。
使用场景:
- 刚
read_csv完立刻跑df.memory_usage(deep=True),确认是否被字符串拖垮 - 做类型转换(如
astype('category'))后,用.sum()对比优化效果 - 调试
copy=True/False行为时,观察索引和列是否意外重复占用内存
注意:df.info(memory_usage='deep') 这个参数只在较新版本 pandas(≥1.5)支持,旧版本无效,别依赖它。
索引也吃内存,别漏掉 index=False
默认 index=True,memory_usage 会把索引内存算进第一个值。但索引本身可能是 RangeIndex(几乎免费),也可能是 object 或 DatetimeIndex(开销不小)。如果你只关心列数据,直接关掉:
df.memory_usage(index=False, deep=True).sum()
常见陷阱:
- 多层索引(
MultiIndex)下,index=True会把所有层级都计入,容易误判主数据列占比 -
Index.memory_usage(deep=True)可单独调用,用于诊断索引是否成为瓶颈 - 用
reset_index(drop=True)后再测,有时比优化列更省事
真正有用的三行诊断模板
别每次手敲参数。这三行是你该粘贴到 Jupyter 开头的:
print("各列深度内存(MB):")<br>print((df.memory_usage(deep=True) / 1024**2).round(2))<br>print(f"总计:{df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
重点在于单位换算和四舍五入——字节数字太长,人眼无法快速判断哪列是问题源。另外,deep=True 必须写死,不能靠 pandas 配置项全局开启;pandas.options.display.memory_usage 只控制 info() 输出,对 memory_usage() 方法无影响。
最常被忽略的一点:memory_usage 返回的是当前快照,它不会告诉你某次 merge 或 groupby 后内存是否泄漏——想查那个,得在操作前后分别调用并对比。函数本身不记录历史,只回答“现在用了多少”。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











