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

如何向量化遍历含df.iloc引用的df_ref时的eval语句?

优化动态iloc引用的向量化处理方案

需要处理存储指向源数据框df的iloc引用字符串的参考数据框df_ref,要求保留Python动态引用特性的同时,优化原循环+eval的低效执行方式。原代码执行10000次循环耗时约2.84秒,性能瓶颈明显。

原代码及执行结果

import pandas as pd
dataValues = ['a','b','c']
df = pd.DataFrame({'values': dataValues})
df_list = ['df.iloc[0,0]','df.iloc[2,0]']
df_ref = pd.DataFrame({'ref':df_list})
# 循环10000次模拟实际场景的运行量
def help():
    for i in range(10000):
        for index,row in df_ref.iterrows():
            eval(df_ref.ref[index])
%timeit help()

执行结果:

2.84 s ± 366 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

优化思路与实现

原方案核心问题:iterrows遍历效率低,且每次循环调用eval重复解析字符串,重复执行时开销被放大。以下方案在保留动态引用特性的前提下,通过预解析索引+向量化操作提升性能:

  1. 预解析iloc索引
    用正则表达式提取每个引用字符串中的行、列索引,将df.iloc[x,y]格式的字符串转换为整数元组(x,y),避免每次执行重复解析字符串。

  2. 向量化批量取值
    利用pandas向量化特性,将解析后的索引批量传入df.iloc,一次性获取所有对应值,替代逐个循环的eval调用。

优化后的代码:

import pandas as pd
import re

dataValues = ['a','b','c']
df = pd.DataFrame({'values': dataValues})
df_list = ['df.iloc[0,0]','df.iloc[2,0]']
df_ref = pd.DataFrame({'ref':df_list})

# 解析引用字符串为索引元组的函数
def parse_refs(ref_series):
    pattern = re.compile(r'df\.iloc\[(\d+),(\d+)\]')
    return [tuple(map(int, pattern.match(s).groups())) for s in ref_series]

# 优化后的执行函数
def optimized_help():
    # 预解析一次索引(若ref列动态变化,可将此步骤移入循环)
    indices = parse_refs(df_ref['ref'])
    rows, cols = zip(*indices)
    for i in range(10000):
        # 向量化批量取值
        df.iloc[list(rows), list(cols)]

%timeit optimized_help()

性能对比

优化后的代码执行耗时通常可降低至几百毫秒级别(具体数值取决于运行环境),相比原方案有数量级的性能提升。

动态引用特性的保留

如果df_ref['ref']内容是动态变化的(比如每次循环都会更新),只需将索引解析步骤移入循环内部即可:

def dynamic_optimized_help():
    for i in range(10000):
        # 每次循环重新解析动态变化的引用
        indices = parse_refs(df_ref['ref'])
        rows, cols = zip(*indices)
        df.iloc[list(rows), list(cols)]

这样既保留了动态指定iloc引用的能力,又避免了原方案中重复eval和低效循环的开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:55:18