Python中基于列数值范围合并DataFrame并映射标签的实现方法
实现DataFrame按多字段+数值范围映射tag列
完全可行,以下是基于Pandas的具体实现方案:
明确数据结构(根据示例图还原)
假设你的两个DataFrame结构如下:
- 主表(记为
df1):包含person、experiment、value三列,是需要补充tag的目标表 - 规则表(记为
df2):包含person、experiment、lower(数值下限)、upper(数值上限)、tag五列,是tag的映射规则表
方案一:交叉合并+条件过滤(通用场景)
逻辑直观,适用于所有数值范围匹配场景:
- 按
person和experiment两个关联字段合并两张表,得到所有可能的组合 - 过滤出
value落在[lower, upper)区间内的行 - 清理冗余列得到最终结果
代码示例:
import pandas as pd # 替换为你的实际数据 df1 = pd.DataFrame({ 'person': ['A', 'A', 'B', 'B', 'C'], 'experiment': ['exp1', 'exp1', 'exp2', 'exp2', 'exp1'], 'value': [5, 15, 22, 8, 3] }) df2 = pd.DataFrame({ 'person': ['A', 'A', 'B', 'C'], 'experiment': ['exp1', 'exp1', 'exp2', 'exp1'], 'lower': [0, 10, 20, 0], 'upper': [10, 20, 30, 5], 'tag': ['low', 'mid', 'high', 'low'] }) # 按关联字段合并 merged = pd.merge(df1, df2, on=['person', 'experiment'], how='left') # 过滤数值范围(可根据需求调整区间开闭,比如改成<=upper) filtered = merged[(merged['value'] >= merged['lower']) & (merged['value'] < merged['upper'])] # 清理冗余列 result = filtered.drop(columns=['lower', 'upper']) print(result)
方案二:merge_asof高效匹配(有序数值场景)
如果value和数值范围是有序的,使用merge_asof效率更高,适合大数据量场景:
- 分别对两张表按数值列排序
- 按
person、experiment分组,匹配符合数值范围的tag
代码示例:
# 对两张表按数值列排序 df1_sorted = df1.sort_values('value') df2_sorted = df2.sort_values('lower') # 执行范围匹配 result = pd.merge_asof( df1_sorted, df2_sorted, on='value', by=['person', 'experiment'], left_open=False, # 表示value >= lower right_open=True # 表示value < upper ) # 恢复原表顺序(可选) result = result.sort_index().drop(columns=['lower', 'upper']) print(result)
注意事项
- 确保
df1的每一行在df2中对应唯一的数值范围,否则会出现重复行,需根据实际需求处理(比如取第一个匹配项,或检查数据规则) - 若数值范围存在重叠,需明确匹配优先级(比如优先匹配下限更高的范围)
内容的提问来源于stack exchange,提问作者Shafiq Javaid
相关产品推荐
相关产品推荐

