
本文介绍如何基于字典映射动态选择列,并仅对满足条件(如大于基准列 'col7')的值计算行级最小值,同时支持返回最小值及对应列名。
本文介绍如何基于字典映射动态选择列,并仅对满足条件(如大于基准列 'col7')的值计算行级最小值,同时支持返回最小值及对应列名。
在实际数据分析中,常需根据某分类字段(如 Col0)动态选取一组相关列,并在这些列中筛选出满足特定条件(例如:值严格大于参考列 'Col7')的元素,再取其最小值。Pandas 的 apply 结合生成器表达式可高效实现该逻辑。
核心思路是:对每一行,先依据 my_dict 获取当前 Col0 对应的候选列名列表;再过滤出存在于当前行且满足 r[col] > r['Col7'] 的列;最后使用 min() 从 (value, column_name) 元组中提取最小值及其来源列。为避免空序列报错,必须传入 default 参数(推荐 (np.nan, ''))。
以下是完整可运行代码:
import pandas as pd
import numpy as np
my_dict = {
'Item1': ['Col1', 'Col3', 'Col6'],
'Item2': ['Col2', 'Col4', 'Col6', 'Col8']
}
df = pd.DataFrame({
'Col0': ['Item1', 'Item2'],
'Col1': [20, 25],
'Col2': [89, 15],
'Col3': [36, 30],
'Col4': [40, 108],
'Col5': [55, 2],
'Col6': [35, 38],
'Col7': [30, 20]
})
# 同时计算 min 值与对应列名
df[['min', 'name']] = df.apply(
lambda r: min(
((r[col], col) for col in my_dict.get(r['Col0'], [])
if col in r and r[col] > r['Col7']),
default=(np.nan, '')
),
axis=1,
result_type='expand'
)
print(df)
输出结果为:
Col0 Col1 Col2 Col3 Col4 Col5 Col6 Col7 min name 0 Item1 20 89 36 40 55 35 30 35 Col6 1 Item2 25 15 30 108 2 38 20 38 Col6
✅ 关键注意事项:
- 条件判断 r[col] > r['Col7'] 必须写在生成器内部,确保只对符合条件的列参与比较;
- 使用 default=(np.nan, '') 防止无匹配项时 min() 抛出 ValueError;
- result_type='expand' 确保元组自动拆分为两列;
- 若只需 min 列而无需列名,可简化为 df['min'] = df.apply(...).str[0];
- 条件可灵活扩展,如 r[col] > r['Col7'] * 1.2 或结合 pd.isna() 排除缺失值。
此方法兼具灵活性与健壮性,适用于多类别、多列映射、带阈值约束的动态聚合场景。











