You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

处理大型Pandas DataFrame时Python代码挂起,CPU使用率降至0%

解决大型Pandas DataFrame操作停滞(CPU 0%、内存拉满)的问题

嘿,我之前也踩过类似的超大型DataFrame坑,你的情况太典型了——本质是物理内存耗尽后,系统被迫依赖虚拟内存(硬盘)进行数据交换,而硬盘速度比内存慢几个数量级,导致进程看起来像是“停滞”了。CPU使用率为0%是因为进程一直在等内存数据从硬盘读入,磁盘使用率显示0可能是系统交换过程中暂时的停顿,或者资源监视器没捕捉到持续的小量读写。下面给你分应急处理和长期优化两个方向梳理解决办法:

一、先救当前停滞的进程(应急方案)

如果你的Python进程还没崩溃,别着急强行关:

  • 立刻关掉所有其他占内存的程序(比如浏览器、IDE的其他窗口),给Python腾物理内存;
  • 打开任务管理器,找到Python进程,右键调优先级为「高」,让系统优先给它分配资源;
  • 要是你开了虚拟内存,确保它的大小足够(建议设为物理内存的1.5-2倍),不过这只是权宜之计,等待时间可能还是很长,做好心理准备。

二、找到内存瓶颈的根源

先搞清楚你在执行什么操作?不同操作的内存需求天差地别:

  • merge、join这类操作要构建哈希表,内存占用可能是原始DataFrame的2-3倍;
  • sort_values需要额外内存存临时排序数据;
  • 哪怕是apply(尤其是逐行apply),也会因为生成大量中间数据占满内存。

先跑个命令看看当前DataFrame的真实内存占用:

print(df.memory_usage(deep=True).sum() / (1024**3))  # 输出总内存(GB)

如果这个数值已经接近你的物理内存,那肯定是内存不够了。

三、长期优化:从根源降低内存占用

1. 给列换更高效的数据类型

Pandas默认会给列分配冗余的类型,比如把int64改成int32(如果数值范围在-2147483648到2147483647之间),低基数的字符串列换成category类型,能直接砍半甚至砍掉90%的内存:

# 转换整数列
df['user_id'] = df['user_id'].astype('int32')
# 把重复率高的字符串列转成category
df['product_type'] = df['product_type'].astype('category')
# 浮点列如果不需要高精度,转成float32
df['price'] = df['price'].astype('float32')

2. 分块处理,不一次性加载全量数据

用read_csv的chunksize参数分块读,每次处理一小部分数据,避免把整个6GB的DataFrame塞进内存:

chunk_size = 1_000_000  # 每次处理100万行
output_path = 'processed_data.csv'

# 先写表头
pd.read_csv('large_data.csv', nrows=0).to_csv(output_path, index=False)

# 分块处理并追加结果
for chunk in pd.read_csv('large_data.csv', chunksize=chunk_size):
    # 这里写你的操作,比如筛选、计算
    filtered_chunk = chunk[chunk['sales'] > 1000]
    # 追加到结果文件
    filtered_chunk.to_csv(output_path, mode='a', header=False, index=False)

3. 用Dask替代Pandas处理超大型数据

如果分块处理太麻烦,直接上Dask——它是为大数据设计的并行框架,语法和Pandas几乎一样,但会自动分块并行处理,不需要你手动管理内存:

import dask.dataframe as dd

# 读取数据,和Pandas几乎一样
ddf = dd.read_csv('large_data.csv')
# 执行操作,比如分组求和
result = ddf.groupby('region')['sales'].sum()
# 计算结果(如果结果能放进内存就转成Pandas,不行就直接写文件)
result.compute().to_csv('region_sales.csv')

4. 避开内存密集型操作

  • 尽量用Pandas的矢量化操作,别用逐行apply——矢量化操作是底层优化的,内存效率高得多;
  • 合并数据前先过滤掉不需要的列和行,减少参与合并的数据量;
  • 排序时用sort_values(kind='mergesort'),它的内存占用比默认的quicksort低很多。

四、关于你说的“静置10-15分钟”

这种情况就是系统在做内存交换(swap):物理内存满了之后,系统把内存里暂时用不到的数据写到硬盘的虚拟内存,等需要的时候再读回来。这个过程特别慢,尤其是内存占满的时候,系统会反复交换数据,导致CPU和磁盘看起来没动静——其实系统全在忙交换,没多余资源响应。等足够久可能会完成,但效率极低,不如从根源优化内存使用。


内容的提问来源于stack exchange,提问作者Chaos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:09:00