如何在Pandas中新增计算列实现IP规则表按优先级和CIDR覆盖IP数排序
问题原因
ipaddress.IPv4Network仅支持接收单个IPv4 CIDR格式字符串作为输入,你直接传入整列Series对象,类型不匹配因此抛出异常assign方法本身不会丢失原有列,你遇到的列缺失问题是错误的赋值逻辑导致的,和assign本身无关
解决方案
分两种实现方式,按需选择:
方式1:先新增地址数字段再排序(推荐,方便后续校验数据)
import pandas as pd import ipaddress # 新增num_addresses列:逐行计算每个CIDR覆盖的IP数量 finalrules = finalrules.assign( num_addresses = lambda df: df['Rule'].apply(lambda cidr: ipaddress.IPv4Network(cidr).num_addresses) ) # 按规则排序:优先级在前,覆盖IP数在后,ascending参数可按需调整排序方向 finalrules_sorted = finalrules.sort_values( by = ['优先级', 'num_addresses'], ascending = [True, False] # 示例为优先级数值越小越靠前,同优先级下覆盖IP越多越靠前 )
方式2:无需新增列,直接在排序时指定key
finalrules_sorted = finalrules.sort_values( by = ['优先级', 'Rule'], # key方法仅对Rule字段做IP数转换,优先级字段保持原值排序 key = lambda col: col if col.name != 'Rule' else col.apply(lambda cidr: ipaddress.IPv4Network(cidr).num_addresses), ascending = [True, False] )
补充说明
- 不需要手动写逐行迭代逻辑,
apply方法已经实现了逐元素处理,比原生Python循环效率更高,也符合pandas的常用写法 - 如果你的CIDR存在主机位未归零的情况(比如
192.168.1.2/24),可以在IPv4Network中加入strict=False参数避免报错:ipaddress.IPv4Network(cidr, strict=False) assign是pandas用于新增/覆盖DataFrame列的方法,返回包含原有所有列+新列的完整DataFrame,不会修改原DataFrame,需要赋值给变量才能保存结果
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

