如何用更Pythonic的方式筛选符合字典阈值的DataFrame子集
优化DataFrame筛选逻辑:更Pythonic的实现方式
需求背景
需要筛选DataFrame中满足以下条件的行:start_count、end_count、received_total任意一列的值,超过其item_id对应字典historical_orders_dict中的阈值。现有代码可正常运行,但希望找到更符合Python风格的实现方式。
现有代码
l = [] for index, row in df_usage.iterrows(): item_id = row['item_id'] try: if ( row['start_count'] > historical_orders_dict[item_id] or row['end_count'] > historical_orders_dict[item_id] or row['received_total'] > historical_orders_dict[item_id] ): l.append(df_usage.loc[[index], :]) except: pass df_too_many_consuables = pd.concat(l).reset_index(drop=True) df_too_many_consuables.shape
示例数据
historical_orders_dict = { '10346': 28644.99, '10877': 28979.99, '10695': 6200.0, '70020': 1960.0, '40265': 57300.0, '91524': 9750.0, '60022': 200.0, '10210': 156.0, '11040': 49350.0} data = { 'item_id': ['10346', '10877', '10695', '70020', '40265', '91524', '60022', '10210','11040'], 'start_count': [100000000, 2, 3, 4, 5, 6, 7, 8, 9], 'end_count': [10, 11, 12, 13, 14, 15, 16, 17, 18], 'received_total': [19, 20, 21, 22, 23, 24, 46, 45, 34]} df_usage = pd.DataFrame(data=data)
优化实现方案
利用Pandas的矢量化操作替代循环,既简洁又高效,完全符合Pythonic风格:
分步实现(可读性优先)
# 1. 为每行映射对应的阈值 df_usage['threshold'] = df_usage['item_id'].map(historical_orders_dict) # 2. 定义需要检查的列 cols_to_check = ['start_count', 'end_count', 'received_total'] # 3. 生成筛选掩码:任意列值超过对应阈值则标记为True mask = df_usage[cols_to_check].gt(df_usage['threshold'], axis=0).any(axis=1) # 4. 筛选行并清理临时列 df_too_many_consuables = df_usage[mask].drop(columns='threshold').reset_index(drop=True) # 查看结果形状 print(df_too_many_consuables.shape)
紧凑实现(代码简洁)
如果追求代码紧凑,也可以合并为一行(可读性略有下降):
cols_to_check = ['start_count', 'end_count', 'received_total'] df_too_many_consuables = df_usage[ df_usage[cols_to_check].gt(df_usage['item_id'].map(historical_orders_dict), axis=0).any(axis=1) ].reset_index(drop=True)
优化优势
- 性能更优:Pandas的矢量化方法(
map、gt、any)基于底层优化,比iterrows()循环快数倍,大数据集下差距更明显。 - 代码简洁:逻辑清晰直观,无需手动循环、异常捕获和列表拼接,维护成本更低。
- 异常处理更安全:
map会自动将字典中不存在的item_id映射为NaN,后续比较时会返回False,等效于原代码中跳过该行的逻辑,同时避免了except:捕获所有异常可能带来的隐藏问题。
内容的提问来源于stack exchange,提问作者Wolfy
相关产品推荐
相关产品推荐

