如何识别Pandas DataFrame中存在重叠的过滤条件行?
问题:过滤掉被完全覆盖的筛选条件行
我有一组优化算法输出的筛选条件数据,需要剔除那些筛选范围被其他行完全覆盖的行,只保留筛选范围唯一的行。比如索引#1的条件(var_1 > 2且var_1 < 5,var_2 > 5且var_2 < 9)完全被索引#0的条件(var_1 > 1且var_1 < 5,var_2 > 5且var_2 < 9)覆盖,所以#1应该被剔除。最终要标记#0、#2、#3为unique_result = True。
原始数据如下:
import pandas as pd df = pd.DataFrame( { "var_1_lower_limit": [1, 2, 1, 3, 2], "var_1_upper_limit": [5, 5, 4, 7, 6], "var_2_lower_limit": [5, 5, 3, 6, 4], "var_2_upper_limit": [9, 9, 8, 9, 7], } )
尝试的两种方法及问题
尝试#1
逻辑是判断当前行的上下限是否<=全局最小值或>=全局最大值,但这个逻辑错误——比如索引#1的var_2_upper_limit等于全局最大值,被错误标记为True。
代码:
def find_unique( var_1_lower_limit, var_1_upper_limit, var_2_lower_limit, var_2_upper_limit ): if ( var_1_lower_limit <= df_filtered.var_1_lower_limit.min() or var_1_upper_limit >= df_filtered.var_1_upper_limit.max() or var_2_lower_limit <= df_filtered.var_2_lower_limit.min() or var_2_upper_limit >= df_filtered.var_2_upper_limit.max() ): return True else: return False df["unique_result"] = df.apply( lambda x: find_unique( x["var_1_lower_limit"], x["var_1_upper_limit"], x["var_2_lower_limit"], x["var_2_upper_limit"], ), axis=1, ) display(df)
尝试#2
思路是先移除当前迭代的行,再判断剩余数据的下限是否小于当前行的下限,但测试单个字段时出现了无法解释的NaN值。
代码:
for i in df.itertuples(): df_filtered = df.drop(df[df.index == i.Index].index) df["low_value_2"] = df_filtered.var_1_lower_limit.apply( lambda x: True if x < i.var_1_lower_limit else False ) display(df)
正确解法
核心逻辑:对于每一行,检查是否存在至少一行其他行能完全覆盖它的筛选范围(即其他行的var_1下限≤当前行var_1下限,var_1上限≥当前行var_1上限,同时var_2的上下限也满足同样的覆盖关系)。如果存在这样的行,说明当前行被完全覆盖,标记为False;否则标记为True。
代码实现:
def is_not_covered(row): # 筛选出所有非当前行且能完全覆盖当前行的记录 mask = ( (df["var_1_lower_limit"] <= row["var_1_lower_limit"]) & (df["var_1_upper_limit"] >= row["var_1_upper_limit"]) & (df["var_2_lower_limit"] <= row["var_2_lower_limit"]) & (df["var_2_upper_limit"] >= row["var_2_upper_limit"]) & (df.index != row.name) # 排除当前行自身 ) # 若没有任何其他行能覆盖当前行,则标记为唯一 return not mask.any() df["unique_result"] = df.apply(is_not_covered, axis=1) display(df)
运行后会得到预期结果:
| 索引 | var_1_lower_limit | var_1_upper_limit | var_2_lower_limit | var_2_upper_limit | unique_result |
|---|---|---|---|---|---|
| 0 | 1 | 5 | 5 | 9 | True |
| 1 | 2 | 5 | 5 | 9 | False |
| 2 | 1 | 4 | 3 | 8 | True |
| 3 | 3 | 7 | 6 | 9 | True |
| 4 | 2 | 6 | 4 | 7 | False |
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

