如何重构多次拼接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
相关产品推荐
相关产品推荐

