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

如何用Numpy或其他库高效实现Pandas分组取每组前10行?

高效筛选DataFrame中每个ID的前10行

方法1:Pandas原生高效方案(推荐)

放弃apply,改用groupby.cumcount()生成分组内的行序号,再通过布尔索引筛选,这是Pandas内置的向量化操作,速度远快于循环式的apply:

k = 10
mask = df.groupby('id').cumcount() < k
result = df[mask]

原理是给每个ID分组内的行分配从0开始的连续序号,只需保留序号小于10的行即可,全程无Python层面的循环,性能拉满。

方法2:纯Numpy实现

如果需要完全基于Numpy的方案,可以按以下步骤操作:

import numpy as np
import pandas as pd

# 先按ID排序,确保同ID的行连续排列
sorted_df = df.sort_values('id')
ids = sorted_df['id'].to_numpy()
float_data = sorted_df.drop('id', axis=1).to_numpy()

# 获取每个唯一ID的起始索引和出现次数
unique_ids, start_indices, counts = np.unique(ids, return_index=True, return_counts=True)
# 计算每个ID需要保留的行数(最多10行)
keep_rows = np.minimum(counts, 10)
# 拼接所有需要保留的行索引
keep_indices = np.concatenate([np.arange(start, start + num) for start, num in zip(start_indices, keep_rows)])

# 重构结果DataFrame
result = pd.DataFrame(float_data[keep_indices], columns=sorted_df.columns[1:])
result['id'] = ids[keep_indices]

这种方法完全依赖Numpy的底层向量化计算,在数据量极大时性能与Pandas原生方案接近,但代码相对繁琐,适合必须使用纯Numpy的场景。

方法3:大数据量场景用Dask

如果你的数据集大到无法装入内存,可以用Dask进行并行处理:

import dask.dataframe as dd

# 将Pandas DataFrame转为Dask DataFrame
ddf = dd.from_pandas(df, npartitions=4)
# 分组取前10行后转回Pandas
result = ddf.groupby('id').head(10).compute()

Dask会自动将数据分片并并行处理,适合TB级别的超大规模数据集,小数据场景反而会有额外的调度开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:00:02