如何基于元组列表在Pandas中创建符合条件的新列?
实现方案
方法1:使用apply逐行匹配(适合小数据集)
定义一个匹配函数,接收每行的col1和col2值,遍历规则列表ls中的元组检查条件,找到符合条件的元组就返回对应结果值,无匹配则返回None,最后用apply将函数应用到每一行:
import pandas as pd ls = [(1,2,10,20,5), (3,4,30,40,10), (5,6,50,60,20)] df_ = pd.DataFrame({'col1': [1.1, 3.5, 5.4, 4.1], 'col2': [11, 35, 44, 41]}) def match_tuple(row): col1_val = row['col1'] col2_val = row['col2'] for tpl in ls: # 同时满足col1在元组第1、2元素之间,col2在第3、4元素之间 if tpl[0] < col1_val < tpl[1] and tpl[2] < col2_val < tpl[3]: return tpl[4] return None df_['result'] = df_.apply(match_tuple, axis=1) print(df_)
运行后输出结果:
col1 col2 result 0 1.1 11 5.0 1 3.5 35 10.0 2 5.4 44 NaN 3 4.1 41 NaN
注:pandas中None会自动显示为NaN,二者功能等价;若要强制显示None,可追加执行:df_['result'] = df_['result'].where(df_['result'].notna(), None)
方法2:向量化匹配(适合大数据集,效率更高)
避免逐行循环,将规则列表转换成DataFrame,通过广播机制批量匹配条件,最后合并结果:
import pandas as pd ls = [(1,2,10,20,5), (3,4,30,40,10), (5,6,50,60,20)] df_ = pd.DataFrame({'col1': [1.1, 3.5, 5.4, 4.1], 'col2': [11, 35, 44, 41]}) # 将规则列表转为结构化DataFrame rules_df = pd.DataFrame(ls, columns=['col1_min', 'col1_max', 'col2_min', 'col2_max', 'result_val']) # 广播匹配:让原DataFrame每行的col1/col2与所有规则做比较 matches = ( (df_['col1'].values[:, None] > rules_df['col1_min'].values) & (df_['col1'].values[:, None] < rules_df['col1_max'].values) & (df_['col2'].values[:, None] > rules_df['col2_min'].values) & (df_['col2'].values[:, None] < rules_df['col2_max'].values) ) # 提取匹配到的结果值,无匹配则设为None df_['result'] = rules_df['result_val'].values[matches.argmax(axis=1)] df_['result'] = df_['result'].where(matches.any(axis=1), None) print(df_)
这种方法无需逐行遍历,处理大规模数据时性能优势明显。
内容的提问来源于stack exchange,提问作者quant
相关产品推荐
相关产品推荐

