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

如何用更高效方法替代Pandas中iloc+append嵌套循环汇总表格?

资助申请学科汇总代码优化

问题场景

现有一张记录资助申请编号与对应学科的表格,单元格值为1代表该申请归属此学科。初始数据处理代码如下:

import pandas as pd
import numpy as np
data={'Application number':[0,1,2,3,4,5,6,7,8,9],
      'Physics':[0,0,1,0,0,0,0,1,1,0],
     'Chemistry':[1,0,0,0,0,0,0,0,0,1],
     'Biology':[0,1,0,1,0,0,1,0,0,0],
     'Mathematics':[0,0,0,0,1,1,0,0,0,0]}

df=pd.DataFrame(data)
# 统计每个申请的学科数量
df['All_Discipline_count']=df.loc[:,'Physics' : 'Mathematics'].sum(axis=1)

需要为每个申请生成对应的学科列表,并汇总学科数量。当前采用嵌套循环实现的代码存在两个问题:一是触发append方法弃用的警告,二是数据量较大时运行速度缓慢:

dfA = pd.DataFrame(columns = ['Application number', 'Discipline_list', 'All_Discipline_count'])

i=0
j=1
Aanvraag_nummer=0
k=df.columns.get_loc("All_Discipline_count")
l=len(df.index)
for i in range (0,l):
    Discipline_count=0
    Discipline_list=" "
    for j in range (1,k):
        if (df.iloc[i,j]==1) & (Discipline_count<df.iloc[i,k]):
            Discipline_list=Discipline_list+ df.columns[j]
            Discipline_count+=1
            if Discipline_count==df.iloc[i,k]:
                Aanvraag_nummer=df.iloc[i,0]
                new_row = {'Application number':Aanvraag_nummer, 'Discipline_list':Discipline_list, 'All_Discipline_count':df.iloc[i,k]}
                dfA = dfA.append(new_row, ignore_index=True)

运行警告:

/tmp/ipykernel_26718/1290491379.py:19: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.

优化实现

利用Pandas的向量化操作替代循环,既能解决警告问题,又能大幅提升运行效率:

方案1:apply结合布尔索引生成学科列表

def get_disciplines(row):
    # 筛选当前行值为1的学科列,拼接成字符串
    return ', '.join(row[row == 1].index)

# 定位所有学科列
discipline_columns = df.loc[:, 'Physics':'Mathematics']
# 生成学科列表列
df['Discipline_list'] = discipline_columns.apply(get_disciplines, axis=1)
# 提取需要的结果列
result_df = df[['Application number', 'Discipline_list', 'All_Discipline_count']]

print(result_df.head(10))

方案2:dot操作实现高效向量化拼接(适合大数据量)

如果处理的申请数量较多,apply的效率仍有提升空间,可使用dot操作直接完成列名拼接:

discipline_columns = df.loc[:, 'Physics':'Mathematics']
# 用dot将列名与对应的值相乘后拼接,最后去除末尾多余的分隔符
df['Discipline_list'] = discipline_columns.dot(discipline_columns.columns + ', ').str.rstrip(', ')
# 整理结果
result_df = df[['Application number', 'Discipline_list', 'All_Discipline_count']]

print(result_df.head(10))

优化说明

  • 两种方案均摒弃了嵌套循环,利用Pandas内置的向量化运算,处理速度比原始代码提升数倍,数据量越大优势越明显
  • 不再使用append方法,彻底消除了弃用警告
  • 默认生成的学科列表用逗号分隔,可读性更强;若需要原始代码的无间隔格式,只需将拼接分隔符改为空字符串即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:55:20