Pandas DataFrame dtype优化后内存异常变化问题求助
问题原因与解释
原DataFrame及备份内存异常变化的原因
这是pandas对韩文(Unicode)字符串的内部存储机制,结合深拷贝实现细节共同导致的:
- pandas的
copy(deep=True)会复制DataFrame的结构与数据,但对于不可变的Python字符串对象(包括韩文列名、韩文数据),Python的字符串intern机制会复用内存中同值的字符串对象,而非创建全新副本。 - 当你对拷贝后的DF执行dtype转换时,若涉及韩文字符串的解析、编码调整(比如将韩文数字字符串转为int8的内部处理),会触发pandas更新原DF中共享字符串对象的元数据(如编码标记、哈希值),导致
memory_usage(deep=True)和sys.getsizeof()测量到内存变化——这两个方法会递归计算所有引用对象的内存,包括共享的字符串对象。 - 部分pandas版本(1.5.x至2.x)在处理非ASCII列名时存在全局缓存逻辑:列名对应的Index对象会被缓存,深拷贝并未完全隔离该缓存,导致拷贝后的操作间接影响原DF的Index内存统计。
韩文数据优化后内存上升的原因
核心是韩文字符串相关的额外内存开销,抵消了int8类型的内存优势:
- 若评分列原本存储为韩文数字字符串(如"일"对应1),转换为int8前需完成字符串到数值的映射,过程中pandas会创建临时中间对象;若原DF存在大量重复韩文字符串,共享的字符串对象内存会被重复统计(
memory_usage(deep=True)会计算所有引用对象的内存,包括临时对象)。 - 韩文列名的存储开销远高于英文:Unicode韩文字符的UTF-8编码长度为3字节,英文仅1字节;且pandas的Index存储非ASCII列名时,会额外占用编码转换、哈希表存储的内存。修改列dtype时,pandas会重新构建列索引的哈希表,导致列名内存占用上升,且该增量超过了int8列节省的内存。
- 若DataFrame中韩文字符串列占比极高,单个评分列的内存节省不足以抵消其他列因操作触发的内存开销,最终整体内存上升。
验证与修复方案
- 验证字符串对象共享:执行
id(df_test['韩文列名'])和id(df_backup['韩文列名']),若返回相同ID,说明字符串对象被复用。 - 彻底隔离拷贝:避免依赖
copy(deep=True),手动创建全新DataFrame:# 仅转换目标列,其他列完全复制 new_df = pd.DataFrame() for col in df_test.columns: if col == '评分列': new_df[col] = df_test[col].astype('int8') else: new_df[col] = df_test[col].copy(deep=True) - 优化韩文字符串存储:将韩文字符串列转为pandas的
StringDtype(),该类型采用矢量化存储,内存占用远低于object dtype的Python字符串对象,可避免共享对象导致的内存统计异常,同时降低整体内存开销:df_test['韩文字符串列'] = df_test['韩文字符串列'].astype('string')
内容的提问来源于stack exchange,提问作者J.Lee.
相关产品推荐
相关产品推荐

