Pandas实现单值/多值列的IP地址与规则映射问题
解决IP地址与规则的递归映射问题
问题分析
你的问题核心在于:
map方法只能匹配完整字符串,当SrcNet/DstNet是多个名称用逗号分隔时,无法拆分后逐个映射,导致出现NaN;- 地址分组(如
ServiceGRP4)对应的Addresses存储的是其他名称,而非直接IP,需要递归解析才能得到最终的IP地址。
解决方案
我们可以通过递归解析函数结合apply方法来实现:先构建名称到地址的映射字典,再对每个名称(或名称组合)递归替换,直到全部解析为IP地址。
完整代码实现
import pandas as pd # 初始化原始数据 df_addresses = pd.DataFrame( { 'Name': ['ServiceIP1', 'ServiceIP2', 'ServiceIP3', 'ServiceGRP4', 'ServiceGRP5', 'ServiceGRP6', 'ServiceIP7', 'ServiceIP8', 'ServiceIP9','ServiceIP10'], 'Addresses': ['1.1.1.1', '2.2.2.2', '3.3.3.3', 'ServiceIP7, ServiceIP8', 'ServiceIP9, ServiceIP10', '6.6.6.6', '7.7.7.7', '8.8.8.8', '9.9.9.9', '10.10.10.10'] } ) df_rules = pd.DataFrame( { 'SrcNet': ['ServiceIP1', 'ServiceIP3', 'ServiceIP1, ServiceIP2', 'ServiceGRP4','ServiceGRP5'], 'DstNet': ['ServiceIP2', 'ServiceIP1', 'ServiceIP3', 'ServiceGRP5','ServiceIP10'], } ) # 构建名称到地址的映射字典 addr_dict = df_addresses.set_index('Name')['Addresses'].to_dict() # 定义递归解析函数 def resolve_ip(name_str, mapping): # 拆分逗号分隔的名称,去除空格 names = [n.strip() for n in name_str.split(',')] resolved_list = [] for name in names: # 获取当前名称对应的地址 target = mapping.get(name, name) # 如果地址仍包含名称(非纯IP),递归解析 if 'Service' in target: resolved_list.append(resolve_ip(target, mapping)) else: resolved_list.append(target) # 拼接成逗号分隔的IP字符串 return ', '.join(resolved_list) # 应用解析函数到SrcNet和DstNet列 df_rules['SrcIP'] = df_rules['SrcNet'].apply(lambda x: resolve_ip(x, addr_dict)) df_rules['DstIP'] = df_rules['DstNet'].apply(lambda x: resolve_ip(x, addr_dict)) # 输出结果 print(df_rules)
运行结果
SrcNet DstNet SrcIP DstIP 0 ServiceIP1 ServiceIP2 1.1.1.1 2.2.2.2 1 ServiceIP3 ServiceIP1 3.3.3.3 1.1.1.1 2 ServiceIP1, ServiceIP2 ServiceIP3 1.1.1.1, 2.2.2.2 3.3.3.3 3 ServiceGRP4 ServiceGRP5 7.7.7.7, 8.8.8.8 9.9.9.9, 10.10.10.10 4 ServiceGRP5 ServiceIP10 9.9.9.9, 10.10.10.10 10.10.10.10
关键说明
- 递归函数
resolve_ip会自动处理两种场景:多个名称的逗号分隔字符串、分组嵌套的名称解析; - 使用
apply替代map,可以对每个单元格的字符串进行自定义拆分和解析; - 映射字典
addr_dict确保了名称到地址的快速查找。
内容的提问来源于stack exchange,提问作者lipos
相关产品推荐
相关产品推荐

