numpy转换文本列遇ArrayMemoryError,为何预估内存超256GiB?
Numpy预估256GiB内存需求的原因
问题重现
我有一个约100MB的中等大小CSV文件,包含20000行数据,执行以下操作时触发内存异常:
ubuntu@ip-172-31-42-52:~/sunshine(XXX)$ python Python 3.10.5 (main, Oct 1 2022, 00:47:42) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pandas as pd >>> df = pd.read_csv('/home/ubuntu/XXX_dataset__full.csv') >>> df.memory_usage() Index 128 url 160000 FOO 160000 BAR 160000 text 160000 dtype: int64 >>> docs = df['text'].values.astype(str) Traceback (most recent call last): File "<stdin>", line 1, in <module> numpy.core._exceptions._ArrayMemoryError: Unable to allocate 256. GiB for an array with shape (20000,) and data type <U3430166 >>> quit()
系统总内存:
MemTotal: 129196996 kB
原因分析
- Pandas与Numpy的字符串存储逻辑差异
Pandas的object类型列(这里的text列属于此类)存储的是字符串的内存引用,64位系统下每个引用占8字节,所以20000行的text列内存占用为20000*8=160000字节,和df.memory_usage()的输出一致。但Numpy的固定长度字符串类型会为数组中每一个元素分配最长字符串的长度对应的内存空间,不管其他元素实际长度。 - 异常长字符串触发内存爆炸
错误信息里的<U3430166表示Unicode字符串类型,每个字符占4字节,最长字符串长度达3430166。Numpy会为20000行的每一行都分配34301664字节的内存,总需求计算为200003430166*4≈256GiB,远超系统可用内存。这说明你的text列中存在异常长的脏数据(比如格式错误、拼接异常的内容)。
解决建议
- 改用列表存储字符串:不需要转换为Numpy数组的话,直接用Pandas的
tolist()获取字符串列表,每个字符串只占用实际所需内存:docs = df['text'].tolist() - 排查并处理异常数据:先检查
text列的最长字符串长度,定位脏数据:
找到异常行后,可以选择截断、删除或修正内容,再进行后续处理。print(df['text'].str.len().max())
内容的提问来源于stack exchange,提问作者chhenning
相关产品推荐
相关产品推荐

