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

如何重构多次拼接DataFrame的函数?优化Python标记变体函数

优化方案:用向量化操作替代循环与多次pd.concat

原函数的性能瓶颈核心在于循环遍历唯一值+反复调用pd.concat——每次concat都会创建新的DataFrame,频繁的内存复制会让时间复杂度飙升至O(n²),处理大CSV文件时自然会严重拖慢速度。针对你的问题,直接给出最优解决方案:

1. 用assign结合lambda实现标记逻辑(一行搞定)

完全可以通过assign+lambda配合pandas的向量化分组操作替代循环,代码极简且性能拉满:

def mark_variants(df):
    return df.assign(
        variante=lambda x: x.groupby('ArtikelNr')['ArtikelNr']
                           .transform('size')
                           .gt(1)
                           .astype(int)
    )

逻辑拆解:

  • groupby('ArtikelNr')['ArtikelNr'].transform('size'):按ArtikelNr分组,计算每组的行数(即该编号的出现次数),并将结果广播到原DataFrame的每一行
  • .gt(1):判断当前行对应的编号出现次数是否大于1,返回布尔值
  • .astype(int):将布尔值转换为0/1格式,匹配你需要的标记规则

2. 重构多次pd.concat的核心思路:避免拆分再合并

原函数将DataFrame拆分为varianten和non_varianten分别处理后再合并,这是完全多余的操作。直接在原DataFrame上新增标记列,从根源上消除了多次concat的性能损耗。

如果确实需要保留拆分逻辑(比如后续要单独处理两类数据),也应该先标记再拆分,而非先拆分再标记:

def mark_variants(df):
    # 先统一完成标记
    df['variante'] = df.groupby('ArtikelNr')['ArtikelNr'].transform('size').gt(1).astype(int)
    # 按需拆分(仅当需要单独处理时执行)
    varianten = df[df['variante'] == 1]
    non_varianten = df[df['variante'] == 0]
    # 合并返回(若无需拆分可直接return df)
    return pd.concat([varianten, non_varianten])

这种方式最多只需要一次concat,性能比原函数提升几个数量级。

性能差异说明

原函数的循环+多次concat耗时会随数据量呈指数增长;优化后的向量化操作是O(n)时间复杂度,处理百万级行的CSV通常仅需几秒,完全可以解决你耗时超4分钟的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:05:18