Python数据处理优化求助:百万级订单高效分组复制拼接
嘿,我太懂你这种百万级订单被循环拖垮的痛苦了!咱们直接说能把速度提上去的核心方向,不用再跟慢到离谱的循环死磕:
核心优化思路:抛弃逐行循环,用批量/向量化操作
你的原代码里的itertuples循环、多次pd.concat和重复query是性能杀手——百万级数据下,这些操作的时间复杂度会直接爆炸。下面是具体的优化方向:
1. 提前预处理promo数据,构建高效查询结构
先把promo表转换成字典+集合的形式,让后续的商品归属判断快到飞起:
import pandas as pd import numpy as np # 示例数据 promo = pd.DataFrame({'main_id':[2,4,6], 'recommended_1':[1,2,8], 'recommended_2':[8,6,9], 'recommended_3':[10,9,10], 'recommended_4': [12,11,11], 'recommended_5': [6,7,8]}) orders = pd.DataFrame({ 'order':['a','a','a','b','b','b','c','c'], 'product':[1,2,3,2,4,9,6,9] }) # 预处理:把主商品存到集合,推荐商品转成{main_id: 推荐商品集合}的字典 main_id_set = set(promo['main_id']) recomm_dict = promo.set_index('main_id')[ ['recommended_1','recommended_2','recommended_3','recommended_4','recommended_5'] ].apply(set, axis=1).to_dict()
2. 批量展开订单(替代循环复制订单)
用groupby+explode实现订单与主商品的交叉展开,自动生成每个主商品对应的订单副本,完全不用逐订单循环:
# 先标记订单中哪些商品是主商品 orders['is_main'] = orders['product'].isin(main_id_set) # 提取每个订单的主商品列表(无主商品的订单可按需求处理,这里保留空列表) order_main_list = orders.groupby('order')['product'].apply( lambda x: x[x.is_main].tolist() if x[x.is_main].size > 0 else [None] ).reset_index(name='main_ids') # 交叉展开:每个主商品对应一个订单副本 expanded_orders = orders.merge(order_main_list, on='order').explode('main_ids').rename(columns={'main_ids': 'main_id'})
3. 批量标记商品类别(用向量化操作替代逐行判断)
用np.select实现批量条件判断,比循环快几个数量级:
# 定义判断条件和对应标签 conditions = [ expanded_orders['product'] == expanded_orders['main_id'], # 主商品 # 判断当前商品是否属于对应main_id的推荐集合 expanded_orders.apply(lambda row: row['product'] in recomm_dict.get(row['main_id'], set()), axis=1) ] labels = ['M', 'R'] # 批量标记,默认是附加商品 expanded_orders['kategoria'] = np.select(conditions, labels, default='A') # 可以去掉不需要的列 expanded_orders = expanded_orders.drop(columns=['is_main']) print(expanded_orders)
4. 超大规模数据进阶:用分布式工具
如果订单量突破千万级,单进程Pandas还是吃力的话,可以直接上:
- Dask:语法和Pandas几乎一致,自动分块并行处理,适合单机器多核场景
- PySpark:分布式计算框架,适合集群处理超大规模数据,百万级数据处理起来毫无压力
原代码慢的核心原因
- 多次
pd.concat:每次都会创建新DataFrame,百万级数据下会产生大量内存拷贝和碎片 - 逐行循环:Python原生循环本身效率低,逐订单处理百万条数据完全是灾难
- 重复查询:多次
query和loc会反复遍历DataFrame,冗余操作太多
内容的提问来源于stack exchange,提问作者patrick_p
相关产品推荐
相关产品推荐

