
本文介绍如何定义一个 Python 函数,根据输入数值在预定义的区间范围内(来自主 DataFrame),高效、准确地查找到对应的返回值,核心依赖 pandas.IntervalIndex 实现闭区间匹配。
本文介绍如何定义一个 python 函数,根据输入数值在预定义的区间范围内(来自主 dataframe),高效、准确地查找到对应的返回值,核心依赖 `pandas.intervalindex` 实现闭区间匹配。
在数据分析与业务逻辑中,常需将连续数值映射到离散类别或等级(如评分分档、费用区间、信用等级等)。此时,硬编码 if-elif-else 易出错且难维护;而基于 DataFrame 的区间查找则更灵活、可配置。推荐使用 pandas.IntervalIndex——它专为高效区间查询设计,支持 closed="both" 实现 [from, until] 闭区间匹配。
以下为完整实现:
import pandas as pd
def assign_value(input_var, df_master):
"""
根据输入数值,在主DataFrame的区间列中查找并返回对应值。
Parameters:
-----------
input_var : int or float
待匹配的数值
df_master : pd.DataFrame
必须包含三列:'value (from)', 'value (until)', 'value to return'
区间为闭区间 [from, until]
Returns:
--------
scalar
匹配到的 'value to return' 值;若无匹配,抛出 ValueError
"""
# 构建闭区间索引
interval_idx = pd.IntervalIndex.from_arrays(
df_master["value (from)"],
df_master["value (until)"],
closed="both"
)
# 查找包含 input_var 的区间位置
mask = interval_idx.contains(input_var)
# 提取匹配行的返回值;squeeze() 确保标量输出(避免 Series)
result = df_master[mask]["value to return"]
if result.empty:
raise ValueError(f"No interval in master DataFrame covers input value {input_var}")
return result.squeeze()
✅ 使用示例:
# 构建主数据表(与问题一致)
df_master = pd.DataFrame({
"value (from)": [0, 31, 51],
"value (until)": [30, 50, 100],
"value to return": [1, 2, 3]
})
print(assign_value(10, df_master)) # 输出:1
print(assign_value(90, df_master)) # 输出:3
print(assign_value(31, df_master)) # 输出:2(边界值有效)
print(assign_value(0, df_master)) # 输出:1(左边界有效)
⚠️ 注意事项:
- 区间必须互斥且覆盖完整范围,否则可能漏匹配或多匹配(当前逻辑仅返回首个匹配项,因 IntervalIndex.contains() 返回布尔数组,且 df_master[mask] 默认按行序返回);
- 若存在重叠区间,请先校验并去重,或改用 pd.cut() + 自定义标签(适用于等宽/有序分箱场景);
- squeeze() 在唯一匹配时安全返回标量;若意外出现多匹配(如区间重叠),会触发 ValueError(can only convert an array of size 1 to a Python scalar),建议生产环境添加 len(result) == 1 显式校验;
- 对于高频调用场景,可将 IntervalIndex 预计算并缓存,避免重复构建开销。
该方案兼顾可读性、健壮性与性能,是处理“数值→分类映射”任务的标准化实践。











