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

Pandas df.loc方法过慢:十万级数据分组赋值优化求助

高效统计用户-文档组合下载次数的Pandas方案

嘿,我太懂你遇到的这个性能糟心事了!10万行的DataFrame用循环+df.loc来赋值,完全是把Pandas的核心优势给浪费了——Pandas天生就是为向量化批量操作设计的,逐组逐行的loc访问会触发无数次索引查找和内存操作,速度慢到离谱简直是必然结果。

问题根源

你之前的思路是分组后用循环+df.loc统计次数,这种方式属于逐元素的“标量操作”。Pandas在处理这类操作时,没法利用底层的C语言优化,每一次loc访问都要单独处理,大数据量下直接拉胯。

最优解决方案:用GroupBy内置聚合函数

直接用groupby搭配.size()或者.count()(如果有专门的下载记录列的话),这是Pandas内部高度优化的向量化操作,速度能提升几个数量级。

最小可复现示例

先构造一个模拟10万行的测试数据集:

import pandas as pd
import numpy as np

# 生成10万行测试数据
np.random.seed(42)
users = np.random.randint(1, 1000, size=100000)
docs = np.random.randint(1, 500, size=100000)
df = pd.DataFrame({'user': users, 'document': docs})
原来的慢方法(不推荐)

假设你之前的代码大概是这样的(注释掉后速度变快,确认是loc的锅):

# 初始化统计列
df['download_count'] = 1

# 慢到离谱的循环+loc赋值
for (user, doc), group in df.groupby(['user', 'document']):
    df.loc[(df['user'] == user) & (df['document'] == doc), 'download_count'] = len(group)
高效替代方案(推荐)

直接用groupby的.transform('size'),这是最简洁且高效的写法:

# 一行代码搞定分组统计并映射回原DataFrame
df['download_count'] = df.groupby(['user', 'document'])['user'].transform('size')

# 如果有专门的下载记录列(比如'download_time'),可以用count更精准:
# df['download_count'] = df.groupby(['user', 'document'])['download_time'].transform('count')

要是你只需要单独的统计结果(不需要合并回原DataFrame),直接用.size()就能得到分组计数的Series:

counts = df.groupby(['user', 'document']).size()

这两种方法都是完全向量化的,运行时间会从原来的几十秒甚至几分钟,压缩到几百毫秒以内。

其他备选方案

如果需要把统计结果整理成宽表格式,可以用pivot_table:

count_table = df.pivot_table(index='user', columns='document', values='user', aggfunc='size', fill_value=0)

或者用pd.value_counts直接得到所有组合的计数:

count_series = df.value_counts(subset=['user', 'document'])

关键提醒

在Pandas里处理大数据时,永远优先用内置的向量化方法,避免写循环逐行/逐组操作。GroupBy的transform、agg、size这些方法都是底层优化过的,性能碾压手动循环+loc。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:24:41