基于多DataFrame列条件匹配 为目标DataFrame新增string_id列
实现DataFrame双条件匹配新增列的解决方案
实现思路
有两种常用实现方案,可根据数据量选择:
- 中小数据量:先按String字段关联两个表,再过滤出Distance落在区间内的匹配结果,最后回写到原表即可
- 大数据量:用
IntervalIndex预先构建第二个表的区间-ID映射,直接按行匹配即可,性能远高于关联过滤方案
代码实现
方案1:merge后过滤(中小数据量)
import pandas as pd # 构造示例第一个df df1 = pd.DataFrame({ 'Timestamp': ['2021-09-01 00:11:37']*4, 'Distance': [0.414, 0.884, 1.354, 1.824], 'String': ['1', '1', '1', '1'] }) # 构造示例第二个df df2 = pd.DataFrame({ 'String_Id': ['1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10'], 'from': [8323.54, 7353.54, 6393.97, 5444.51, 4505.14, 3545.57, 2596.11, 1687.00, 848.68, 0.00], 'to': [9272.67, 8323.54, 7353.54, 6393.97, 5444.51, 4505.14, 3545.57, 2596.11, 1687, 848.68], 'String_old_name': ['1']*10 }) # 核心逻辑 # 1. 按String字段关联两个表 merged = df1.merge(df2, left_on='String', right_on='String_old_name', how='left') # 2. 过滤出Distance落在[from, to]区间的匹配行 filtered = merged[(merged['Distance'] >= merged['from']) & (merged['Distance'] <= merged['to'])] # 3. 匹配结果回写到原df1 result = df1.merge(filtered[['Timestamp', 'Distance', 'String', 'String_Id']], on=['Timestamp', 'Distance', 'String'], how='left') # 4. 重命名为要求的列名 result.rename(columns={'String_Id': 'string_id'}, inplace=True)
方案2:IntervalIndex匹配(大数据量高性能方案)
# 1. 预先构建String->区间-ID的映射关系 id_mapping = {} for name, group in df2.groupby('String_old_name'): # 构建左闭右闭的区间索引 intervals = pd.IntervalIndex.from_arrays(group['from'], group['to'], closed='both') id_mapping[name] = pd.Series(group['String_Id'].values, index=intervals) # 2. 直接按行匹配生成新列,存在匹配不到的场景可加try-except返回NaN df1['string_id'] = df1.apply( lambda x: id_mapping[x['String']].loc[x['Distance']] if x['String'] in id_mapping else pd.NA, axis=1 )
结果说明
示例中4行数据的Distance均落在0.00-848.68区间,因此最终生成的string_id列的值均为1.10,符合预期。
内容的提问来源于stack exchange,提问作者hania_w
相关产品推荐
相关产品推荐

