基于多条件从多列查找 为Pandas DataFrame添加因子列
解决方案
针对大规模数据,推荐两种高效矢量化方案,避免循环操作:
方案一:IntervalIndex + pd.lookup(性能最优)
利用区间索引快速定位行,再通过pd.lookup动态匹配Type对应的列,全程矢量化操作,速度极快。
import pandas as pd # 1. 创建区间索引,获取每行Value对应的Lookup行索引 intervals = pd.IntervalIndex.from_arrays(df_Lookup['Min Value'], df_Lookup['Max Value'], closed='both') lookup_row_indices = intervals.get_indexer(df_RawData['Value']) # 2. 生成匹配的列名:将Type转为"Type X"格式 df_RawData['type_col'] = 'Type ' + df_RawData['Type'].astype(str) # 3. 通过行索引+列名提取因子值 df_RawData['Factor'] = pd.lookup(lookup_row_indices, df_RawData['type_col'], df_Lookup) # 清理临时列 df_RawData.drop('type_col', axis=1, inplace=True) print(df_RawData)
方案二:Melt转长格式 + merge_asof(逻辑更直观)
将宽格式的df_Lookup转为长格式,再用merge_asof实现区间+Type的双条件匹配,适合需要扩展逻辑的场景。
import pandas as pd # 1. 将Lookup表转为长格式 df_lookup_long = df_Lookup.melt( id_vars=['Min Value', 'Max Value'], var_name='Type', value_name='Factor' ) # 提取Type中的数字并转为整数 df_lookup_long['Type'] = df_lookup_long['Type'].str.extract('(\d+)').astype(int) # 2. merge_asof要求左右表按匹配字段排序 df_lookup_sorted = df_lookup_long.sort_values('Min Value') df_raw_sorted = df_RawData.sort_values('Value') # 3. 执行区间+Type匹配 result = pd.merge_asof( df_raw_sorted, df_lookup_sorted, left_on='Value', right_on='Min Value', by='Type', # 同时匹配Type字段 direction='backward' # 找到小于等于Value的最大Min Value ) # 过滤掉Value超出Max Value的无效匹配 result = result[result['Value'] <= result['Max Value']] # 恢复原数据顺序并保留目标列 result = result.sort_index()[['Value', 'Type', 'Factor']] print(result)
内容的提问来源于stack exchange,提问作者Actuarian
相关产品推荐
相关产品推荐

