Python广告数据分析代码运行缓慢的原因及优化建议咨询
代码性能瓶颈分析与优化方案
一、性能慢的核心原因
- 重复低效的DataFrame切片:内层循环中每次从原始DataFrame开始逐列过滤,每次切片都会生成新的DataFrame对象并拷贝数据,布尔索引的反复调用带来巨大的内存和CPU开销。
- 暴力枚举导致计算量爆炸:总循环次数达
C(47,4)*2^4=2,853,840次,每次循环都要执行多次过滤和均值计算,完全没有利用pandas的向量化/分组优化能力。 - 不必要的对象转换:
set_groups中将结果转为np.array(dtype=object),不仅无意义,还会增加后续循环的元素访问开销。 - 未提前过滤高绩效样本:每次都在全量数据中计算组均值,而实际上只有包含高绩效广告的组才可能满足阈值条件,全量计算浪费大量资源。
二、针对性优化方案
1. 提前过滤高绩效广告子集
先筛选出KPI达标的广告,后续所有计算仅基于这个子集,直接减少数据处理量:
# 替换原identify_clusters中的初始数据处理逻辑 high_perf_df = df[df[KPI] > KPI_threshhold].copy()
2. 用GroupBy替代嵌套循环
利用pandas原生的groupby操作,一次性处理同一特征组合下的所有值分组,底层由C实现,性能远高于Python循环:
def identify_clusters_optimized(df, KPI, KPI_threshhold, max_size, min_size, n): # 提前过滤高绩效样本 high_perf_df = df[df[KPI] > KPI_threshhold].copy() columns = df.columns[4:] output = [] # 遍历所有特征组合 for comb in itertools.combinations(columns, n): # 按当前特征组合分组 grouped = high_perf_df.groupby(list(comb)) # 遍历每个分组 for vals, group in grouped: # 过滤组大小符合要求的结果 if min_size <= len(group) <= max_size: output.append([comb, list(vals), group['ad_id'].values]) return output
3. 移除冗余的set_groups函数
原set_groups生成的特征组合与值组合列表完全可以在优化后的identify_clusters中直接生成,无需额外转换:
# 直接删除原set_groups函数,优化后的identify_clusters不再依赖它
4. 并行化处理特征组合
由于每个特征组合的分组计算是独立的,可以用多进程并行处理,充分利用CPU多核:
from joblib import Parallel, delayed def process_single_comb(comb, high_perf_df, min_size, max_size): grouped = high_perf_df.groupby(list(comb)) results = [] for vals, group in grouped: if min_size <= len(group) <= max_size: results.append([comb, list(vals), group['ad_id'].values]) return results def identify_clusters_parallel(df, KPI, KPI_threshhold, max_size, min_size, n): high_perf_df = df[df[KPI] > KPI_threshhold].copy() columns = df.columns[4:] all_combs = list(itertools.combinations(columns, n)) # 并行处理,n_jobs=-1表示使用所有可用CPU核心 all_results = Parallel(n_jobs=-1)( delayed(process_single_comb)(comb, high_perf_df, min_size, max_size) for comb in all_combs ) # 合并所有并行结果 output = [] for res in all_results: output.extend(res) return output
5. 主函数调用修改
替换原主函数中的逻辑,直接调用优化后的函数:
## Main df = pd.read_excel('data.xlsx', sheet_name='name') # 调用优化后的单进程版本 output = identify_clusters_optimized(df, 'KPI_var', 0.0015, 6, 4, 4) # 或调用并行版本 # output = identify_clusters_parallel(df, 'KPI_var', 0.0015, 6, 4, 4) print(output)
三、优化效果说明
- 提前过滤高绩效样本可减少50%以上的数据处理量(取决于达标率);
groupby替代嵌套循环可将单特征组合的处理速度提升10-100倍;- 并行化处理可进一步将总耗时降低至原耗时的1/CPU核心数(比如8核CPU可降到15分钟以内)。
内容的提问来源于stack exchange,提问作者James Freedman
相关产品推荐
相关产品推荐

