Reputation: 1
I have following two DataFrame with Addresses IP and Rules. I would like to map IP addresses to rules. I'm partially successful when Name is a single IP, but unsuccessful with ServiceGroups and then Rules have more than one Service.
Here's my code:
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'],
}
)
df_rules['SrcIP'] = df_rules.SrcNet.map(df_addresses.set_index('Name').Addresses)
df_rules['DstIP'] = df_rules.DstNet.map(df_addresses.set_index('Name').Addresses)
The outcome is:
print(df_addresses)
Name Addresses
0 ServiceIP1 1.1.1.1
1 ServiceIP2 2.2.2.2
2 ServiceIP3 3.3.3.3
3 ServiceGRP4 ServiceIP7, ServiceIP8
4 ServiceGRP5 ServiceIP9, ServiceIP10
5 ServiceGRP6 6.6.6.6
6 ServiceIP7 7.7.7.7
7 ServiceIP8 8.8.8.8
8 ServiceIP9 9.9.9.9
9 ServiceIP10 10.10.10.10
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 NaN 3.3.3.3
3 ServiceGRP4 ServiceGRP5 ServiceIP7, ServiceIP8 ServiceIP9, ServiceIP10
4 ServiceGRP5 ServiceIP10 ServiceIP9, ServiceIP10 10.10.10.10
I would like it to have ONLY IPs in the SrcIP and DstIP column! Like this
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
Any idea how I can map it with pandas or any alternative solutions?
Upvotes: 0
Views: 150
Reputation: 261900
You need a double mapping, with an intermediate DataFrame with split and exploded Addresses:
# initial mapper
s = df_addresses.set_index('Name')['Addresses']
# split/explode addresses
s2 = df_addresses['Addresses'].str.split(',\s*').explode()
mapper = (df_addresses
.assign(Addresses=s2.map(s).fillna(s2).groupby(level=0).agg(', '.join))
.set_index('Name')['Addresses']
)
df_rules['SrcIP'] = df_rules['SrcNet'].map(mapper)
df_rules['DstIP'] = df_rules['DstNet'].map(mapper)
output:
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 NaN 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
Upvotes: 1