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

请求优化检测DataFrame列差异的Python低效函数

优化DataFrame列对差异检测函数

问题背景

需要检测DataFrame中指定列对的差异,为每行生成记录差异对应标识的列表,但原函数采用逐行遍历的实现方式,运行效率低下。

DataFrame结构示例:

1    2    3    4   ...   19    20
------------------------
foo  Fou  bar  bar ...   noob  noob1

原函数代码:

def find_changes_in_cols(df):
    df['Change_Info'] = ''
    for i in range(len(df)):
        liste = []
        if df.at[i, '1'] != df.at[i, '2']:
            liste.append('Downlink')
        if df.at[i, '3'] != df.at[i, '4']:
            liste.append('Uplink')
        if df.at[i, '5'] != df.at[i, '6']:
            liste.append('Inp')
        if df.at[i, '7'] != df.at[i, '8']:
            liste.append('Power')
        if df.at[i, '9'] != df.at[i, '10']:
            liste.append('SNR')
        if df.at[i, '11'] != df.at[i, '12']:
            liste.append('RFI')
        if df.at[i, '13'] != df.at[i, '14']:
            liste.append('UPBO')
        if df.at[i, '15'] != df.at[i, '16']:
            liste.append('DPBO')
        if df.at[i, '17'] != df.at[i, '18']:
            liste.append('VN')
        if df.at[i, '19'] != df.at[i, '20']:
            liste.append('Vect')
        
        df.at[i, 'Change_Info'] = liste  
    return df

原函数输出示例:

1    2    3    4   ...   19    20     Change_Info
------------------------
foo  Fou  bar  bar ...   noob  noob1  [Downlink, Vect]

优化方案

利用Pandas的矢量化操作替代逐行循环,大幅提升运行效率,同时增强代码可维护性。

基础优化版

import pandas as pd

def find_changes_in_cols_optimized(df):
    # 集中定义列对与对应标识的映射,便于后续修改维护
    column_pairs = [
        ('1', '2', 'Downlink'),
        ('3', '4', 'Uplink'),
        ('5', '6', 'Inp'),
        ('7', '8', 'Power'),
        ('9', '10', 'SNR'),
        ('11', '12', 'RFI'),
        ('13', '14', 'UPBO'),
        ('15', '16', 'DPBO'),
        ('17', '18', 'VN'),
        ('19', '20', 'Vect'),
    ]
    
    # 为每个列对生成差异标记列(差异时为对应标识,否则为None)
    change_cols = []
    for col1, col2, label in column_pairs:
        mask = df[col1] != df[col2]
        change_cols.append(mask.map(lambda x: label if x else None))
    
    # 按行合并所有标记列,过滤掉None值得到最终差异列表
    df['Change_Info'] = pd.concat(change_cols, axis=1).apply(
        lambda row: [item for item in row if item is not None], axis=1
    )
    
    return df

优化说明

  • 矢量化运算:避免了df.at逐行访问的低效操作,通过列级批量处理所有行,在数据量较大时性能提升显著。
  • 可维护性:列对与标识的映射集中管理,新增或修改规则只需调整column_pairs列表,无需修改大量重复判断。

超大数据集终极优化版

如果处理百万级以上行的数据集,apply(axis=1)仍有性能瓶颈,可直接操作NumPy数组进一步提速:

def find_changes_in_cols_ultimate(df):
    column_pairs = [
        ('1', '2', 'Downlink'),
        ('3', '4', 'Uplink'),
        ('5', '6', 'Inp'),
        ('7', '8', 'Power'),
        ('9', '10', 'SNR'),
        ('11', '12', 'RFI'),
        ('13', '14', 'UPBO'),
        ('15', '16', 'DPBO'),
        ('17', '18', 'VN'),
        ('19', '20', 'Vect'),
    ]
    
    # 预先计算所有列对的差异掩码(NumPy数组)
    masks = [(df[col1] != df[col2]).values for col1, col2, _ in column_pairs]
    labels = [label for _, _, label in column_pairs]
    
    # 用列表推导逐行生成结果,避开Pandas apply的额外开销
    df['Change_Info'] = [
        [labels[j] for j in range(len(masks)) if masks[j][i]]
        for i in range(len(df))
    ]
    
    return df

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:50:27