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

优化等效Excel SUMIFS功能的Python脚本以缩短执行时间

问题背景

我正尝试复现Excel中的SUMIFS函数功能,对应公式近似为:accumulation1 =SUMIFS(value; $fin$1:$fin$5; ini$1)。该公式的作用是查找并累加end列表中与对应ini匹配的value值。
计算示例:id3的accumulation1取值逻辑为,查找ini=11对应endPoint的value值,即id1和id5的value之和(3+5=8)。
后续我需要新增累加列并重复该计算逻辑,总计要执行1004次,用于河网路径遍历取值计算。

示例数据
idinifinvalueaccumulation1accumulation2sumOfAccumulation
110115005
29100000
3111228010
4121312811
505113003
现有代码
connection = psycopg2.connect(dbname=DB_NAME,user=DB_USER, password=DB_PWD, host=DB_HOST, port=DB_PORT)
cursor = connection.cursor(cursor_factory=psycopg2.extras.DictCursor)

data = pdsql.read_sql_query("select id_bdcarth, id_nd_ini::int ini, id_nd_fin::int fin, v from tempturbi.tmp_somme_v19",connection)

Endtest=1
 
#loop until Endtest = 0 : 
    #create a new column accumulation  
    for i in data.ini:
        acc=[]
        acc=data.v.loc[data.fin==i] # get values of the upstream segments
        acc=sum(acc) 
        #save acc in accumulation 

    Endtest=data.sum(accumulation)     
    
    print("--- %s seconds ---" % (time.time() - start_time))
河网示意图

河网示意图

性能优化方案
  • 替换逐行循环逻辑为pandas向量化操作:原代码中for循环遍历每个ini值、再逐行匹配fin的写法时间复杂度为O(n²),可以先按fin分组计算value的总和,再用map映射到ini列上,单次计算复杂度直接降到O(n),仅这一项优化就能把129秒的耗时压缩到秒级。示例代码:
# 预计算每个fin对应的value总和
fin_sum = data.groupby('fin')['v'].sum()
# 直接映射得到当前轮次的accumulation列
data[f'accumulation_{step}'] = data['ini'].map(fin_sum).fillna(0)
  • 避免重复创建列存储中间结果:如果不需要留存每一步的accumulation值,直接更新v列作为下一轮计算的输入即可,减少内存占用和写入开销。
  • 数据库层面提前计算:如果数据量超过10万行,直接在PostgreSQL中用递归CTE完成河网的路径累加计算,比拉取到本地用pandas处理快3-10倍,递归CTE天然适配有向无环的河网遍历场景。
  • 替换原生sum函数:原代码中用Python内置sum处理pandas序列,直接用pandas自带的.sum()方法速度更快,因为底层是C实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:45:04