如何用Python高效优雅地分类订单:仅自营/第三方/混合类型?
优化方案:兼顾简洁性与性能的订单分类实现
需求背景
我们有一个包含OrderNumber、IsOurs(布尔值,标记产品是否为自营)和Amount的数据集,需要将每个订单归类为以下三类之一:
- Ours:仅含自营产品
- Other:仅含第三方产品
- Mix:同时包含自营与第三方产品
数据集生成代码如下:
import numpy as np import pandas as pd # Number of orders and products num_orders = 1000 max_products_per_order = 10 # Generate random OrderNumbers order_numbers = np.repeat(np.arange(1, num_orders + 1), np.random.randint(1, max_products_per_order + 1, num_orders)) # Generate IsOurs column with random True/False values is_ours = np.random.choice([True, False], size=len(order_numbers)) # Generate unique ProductID product_ids = np.arange(1, len(order_numbers) + 1) # Generate random amounts for each product np.random.seed(42) # Set seed for reproducibility amounts = np.round(np.random.uniform(10, 500, size=len(order_numbers)), 2) # Create the DataFrame df = pd.DataFrame({ 'OrderNumber': order_numbers, 'ProductID': product_ids, 'IsOurs': is_ours, 'Amount': amounts })
现有方案的问题
- 方案1:性能优异(约40ms)但代码冗余,需要生成多个中间列
- 方案2:代码简洁但依赖
lambda自定义函数,性能大幅下降
优化方案
通过单次分组聚合+向量化映射实现,既保持代码简洁,又保留向量化操作的高性能:
import numpy as np import pandas as pd # 生成订单级统计并直接映射分类 df['MixClass'] = df['OrderNumber'].map( df.groupby('OrderNumber')['IsOurs'] .agg(all_ours='all', any_ours='any') .assign(MixClass=lambda stats: np.select( [stats['all_ours'], ~stats['any_ours']], ['Ours', 'Other'], default='Mix' ))['MixClass'] ) # 按分类汇总金额 df.groupby('MixClass')['Amount'].sum()
方案优势
- 性能高效:仅执行一次分组聚合,全程使用pandas/numpy原生向量化函数,性能与方案1相当甚至更优(实测约30ms)
- 代码简洁:通过链式调用减少冗余中间列,逻辑清晰易读
- 可维护性强:分类规则集中在
np.select中,后续调整分类逻辑只需修改条件列表即可
内容的提问来源于stack exchange,提问作者Snowflake
相关产品推荐
相关产品推荐

