Python Pandas:判断DataFrame值是否在另一个不等长DataFrame的任意区间中
区间匹配解决方案:判断值是否落在任意DataFrame区间内
需求说明
现有两个行数不等的DataFrame:
df:包含min_val和max_val列,代表一系列区间df1:包含val列,需判断每个值是否落在df的任意区间内
最终需生成新DataFrame,包含val、匹配到的区间(无匹配则为NaN)、nameTag字段(标记within或not within)。此前逐行匹配的方案无法识别跨行区间匹配(如val=2落在df的0-4区间),需替换为可行方案。
示例输入
import pandas as pd import numpy as np # df区间数据 df = pd.DataFrame({ 'min_val': [0,5,10,15,20,25], 'max_val': [4,9,14,19,24,29] }) # df1待判断值数据 df1 = pd.DataFrame({ 'val': [1,6,2,np.nan,34] })
解决方案
方案1:笛卡尔积匹配(适合小数据量)
通过生成所有值与区间的组合,筛选符合条件的匹配项,再合并回原数据:
# 为df1添加临时索引,用于后续合并 df1['temp_idx'] = df1.index # 生成所有val与区间的组合,筛选val落在区间内的记录 matches = df1.merge(df, how='cross') matches = matches[(matches['val'] >= matches['min_val']) & (matches['val'] <= matches['max_val'])] # 合并回原df1,保留每个val的第一个匹配区间 result = df1.merge(matches[['temp_idx', 'min_val', 'max_val']], on='temp_idx', how='left') # 标记是否在区间内 result['nameTag'] = np.where(result['min_val'].notna(), 'within', 'not within') # 清理临时列并调整顺序 result = result.drop('temp_idx', axis=1)[['val', 'min_val', 'max_val', 'nameTag']].reset_index(drop=True)
方案2:区间索引匹配(适合大数据量)
利用Pandas的IntervalIndex和pd.cut实现高效匹配,无需生成笛卡尔积:
# 从df生成区间索引(closed='both'表示包含区间两端) bins = pd.IntervalIndex.from_arrays(df['min_val'], df['max_val'], closed='both') # 匹配每个val对应的区间 df1['interval'] = pd.cut(df1['val'], bins=bins) # 从匹配到的区间提取min和max值 df1['min_val'] = df1['interval'].apply(lambda x: x.left if pd.notna(x) else np.nan) df1['max_val'] = df1['interval'].apply(lambda x: x.right if pd.notna(x) else np.nan) # 标记是否在区间内 df1['nameTag'] = np.where(df1['interval'].notna(), 'within', 'not within') # 清理临时列并调整顺序 result = df1[['val', 'min_val', 'max_val', 'nameTag']].reset_index(drop=True)
示例输出
val min_val max_val nameTag 0 1.0 0.0 4.0 within 1 6.0 5.0 9.0 within 2 2.0 0.0 4.0 within 3 NaN NaN NaN not within 4 34.0 NaN NaN not within
内容的提问来源于stack exchange,提问作者Yiannis
相关产品推荐
相关产品推荐

