DataFrame中有序CIDR校验字面相等及重叠并筛选唯一CIDR的高效方法
高效筛选无重叠且未重复CIDR的实现方案
前置依赖
你需要用到以下库,其中ipaddress是Python标准库无需额外安装,netaddr可通过pip install netaddr快速安装:
pandas:用于DataFrame矢量化操作netaddr:用于高效IP段聚合、重叠校验ipaddress:可选,用于CIDR合法性校验
实现步骤
第一步:快速过滤字面完全相等的CIDR
直接用pandas内置的isin矢量化方法,O(1)时间复杂度即可筛除第一列中已经在第二列字面存在的记录:
import pandas as pd from netaddr import IPSet # 假设你的DataFrame名为df,两列名分别为cidr_col1、cidr_col2 # 先提取第二列的所有CIDR到集合,加速比对 col2_cidr_set = set(df['cidr_col2'].dropna()) # 过滤第一列中字面不重复的CIDR no_exact_match = df[~df['cidr_col1'].isin(col2_cidr_set)]['cidr_col1'].dropna()
第二步:构建第二列的聚合IP集合,批量校验重叠
IPSet会自动将所有输入的CIDR聚合为连续的无重叠IP段,判断单个CIDR是否和整个集合重叠的时间复杂度极低,无需逐一遍历第二列所有CIDR:
# 构建第二列所有CIDR的聚合IP集合 col2_ipset = IPSet(df['cidr_col2'].dropna().tolist()) # 定义校验重叠的函数,直接用IPSet的交集判断 def has_overlap(cidr): try: return not IPSet([cidr]).isdisjoint(col2_ipset) except: # 处理非法CIDR格式的情况,可根据需求调整返回值 return True # 矢量化应用校验函数,筛选出既不字面相等也无重叠的CIDR unique_cidrs = no_exact_match[~no_exact_match.apply(has_overlap)].tolist()
效率提升说明
- 相比两层for循环的O(n*m)时间复杂度,该方案的时间复杂度接近O(n+m),数据集规模越大提升越明显
- 如果你的CIDR均为IPv4,还可以提前将CIDR转换为起止整数,用区间树做重叠校验,性能还能再提升30%以上
如果你不想引入第三方库
netaddr,可以将第二列所有CIDR转换为「起始IP整数、结束IP整数」的元组,按起始IP排序后,对第一列每个CIDR的起止IP用二分查找判断是否落入任意区间,性能也远高于循环比对。
内容的提问来源于stack exchange,提问作者Engr_Ondigo
相关产品推荐
相关产品推荐

