如何用Python计算两个数值范围的双向重叠占比?
双向数值范围重叠占比计算方案
没问题,我来帮你完善这个双向重叠占比的计算方案。你已经搞定了重叠判断的核心逻辑,接下来只需要基于这个扩展出占比计算的部分,同时处理一些边界情况就可以了。
核心计算逻辑
先明确两个方向占比的定义:
- A相对于B的重叠占比:重叠区间的长度 ÷ B范围的总长度 × 100%
- B相对于A的重叠占比:重叠区间的长度 ÷ A范围的总长度 × 100%
需要额外处理的边界情况:
- 输入的范围是否合法(左边界必须 ≤ 右边界),避免无效输入报错
- 当某个范围的总长度为0(比如
[5,5])时,要避免除以0的错误 - 两个范围无重叠时,两个占比都为0%
完整Python实现
def calculate_overlap_ratios(x1, x2, y1, y2): # 验证输入的数值范围合法性 if x1 > x2 or y1 > y2: raise ValueError("输入的数值范围不合法,左边界必须小于等于右边界") # 判断两个范围是否重叠(复用你已实现的函数) if not is_overlapping(x1, x2, y1, y2): return (0.0, 0.0) # 无重叠时双向占比均为0% # 计算重叠区间的起始、结束和长度 overlap_start = max(x1, y1) overlap_end = min(x2, y2) overlap_length = overlap_end - overlap_start # 计算两个范围的总长度 len_a = x2 - x1 len_b = y2 - y1 # 计算双向占比,处理范围长度为0的情况(避免除以0) ratio_a_to_b = (overlap_length / len_b) * 100 if len_b != 0 else 0.0 ratio_b_to_a = (overlap_length / len_a) * 100 if len_a != 0 else 0.0 # 保留两位小数让结果更直观 return (round(ratio_a_to_b, 2), round(ratio_b_to_a, 2)) # 你已实现的重叠判断函数 def is_overlapping(x1, x2, y1, y2): return max(x1, y1) <= min(x2, y2)
测试用例验证
用你给出的示例和其他典型场景测试:
# 示例场景:A=[1,100], B=[25,100] ratio_a_to_b, ratio_b_to_a = calculate_overlap_ratios(1, 100, 25, 100) print(f"A相对于B的重叠占比:{ratio_a_to_b}%") # 输出:100.0% print(f"B相对于A的重叠占比:{ratio_b_to_a}%") # 输出:75.0% # 部分重叠场景:A=[10,50], B=[30,70] ratio_a_to_b, ratio_b_to_a = calculate_overlap_ratios(10, 50, 30, 70) print(f"A相对于B的重叠占比:{ratio_a_to_b}%") # 输出:50.0% print(f"B相对于A的重叠占比:{ratio_b_to_a}%") # 输出:50.0% # 无重叠场景:A=[1,20], B=[30,50] ratio_a_to_b, ratio_b_to_a = calculate_overlap_ratios(1, 20, 30, 50) print(f"A相对于B的重叠占比:{ratio_a_to_b}%") # 输出:0.0% print(f"B相对于A的重叠占比:{ratio_b_to_a}%") # 输出:0.0% # B完全包含A场景:A=[20,80], B=[1,100] ratio_a_to_b, ratio_b_to_a = calculate_overlap_ratios(20, 80, 1, 100) print(f"A相对于B的重叠占比:{ratio_a_to_b}%") # 输出:60.61% print(f"B相对于A的重叠占比:{ratio_b_to_a}%") # 输出:100.0%
细节说明
- 输入验证:提前拦截
x1 > x2或y1 > y2的无效范围,避免后续计算出现异常 - 除以0处理:当某个范围是单点(长度为0)时,直接返回0%占比,避免
ZeroDivisionError - 结果格式化:用
round()保留两位小数,让输出更易读
内容的提问来源于stack exchange,提问作者Praderas
相关产品推荐
相关产品推荐

