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

如何加速Pandas DataFrame中所有行对的嵌套循环?

问题描述

我有一个约8万行的DataFrame,格式如下:

df = pd.DataFrame({'Year': [1900, 1902, 1903], 'Name': ['Tom', 'Dick', 'Harry']})

   Year   Name
0  1900    Tom
1  1902   Dick
2  1903  Harry

我需要以Name列的每一组组合(含自身与自身的组合)作为参数调用函数,当前使用以下代码实现(用print替代函数调用):

for i, n1 in enumerate(df.itertuples()):
    for n2 in df[i:].itertuples():
        print(n1.Name, n2.Name)

请问是否有我忽略的加速方法?另外,我需要跟踪每个名称对的索引,若使用itertools.combinations处理索引,仍需执行代价较高的df.loc调用。

解决方案

一、核心加速思路

你的代码核心问题是Python级嵌套循环效率极低,加上反复从DataFrame读取数据的额外开销,导致整体速度缓慢。可以通过以下两点大幅优化:

1. 提前提取Name列的numpy数组

将Name列转为numpy数组,直接通过索引访问元素的速度比df.loc或itertuples的对象属性访问快一个数量级:

names = df['Name'].values

2. 用itertools生成组合替代嵌套循环

itertools模块的组合生成逻辑是C语言实现的,远快于Python原生循环。结合你的需求(包含自身与自身的组合),使用combinations_with_replacement生成索引对,再通过提前提取的numpy数组获取名称,完全规避df.loc的高代价调用:

import itertools

# 生成所有满足 j >= i 的索引对
for idx1, idx2 in itertools.combinations_with_replacement(df.index, 2):
    name1 = names[idx1]
    name2 = names[idx2]
    # 替换为你的函数调用,例如 func(name1, name2)
    print(name1, name2)

若你需要的是不含自身与自身的严格无序对(j > i),则改用itertools.combinations(df.index, 2)即可。

二、优化效果的核心原因

  • 消除Python循环开销:itertools的组合生成在底层执行,避免了Python级循环的性能损耗。
  • 简化数据访问路径:numpy数组的索引访问是直接内存操作,比DataFrame的属性/索引访问少了大量封装层的开销。
  • 低内存占用:itertools采用惰性生成逻辑,不会一次性生成所有组合(8万行的组合数约3.2亿,直接生成会耗尽内存),仅按需生成每组数据。

三、额外优化建议

如果你的函数支持批量处理,可以尝试用广播生成组合数组,但需注意8万行的组合规模会占用极大内存,迭代处理仍是更稳妥的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:02:39