I have a csv file that contains a column of CIDR IPs and a column that has the location of where that IP is being used, like this:
| CIDR | Location |
| ------------ | ---------- |
| x.x.x.x/24 | OFFICE |
| x.x.x.x/24 | DATACENTER |
| x.x.x.x/25 | DATACENTER |
| x.x.x.x/26 | DATACENTER |
And the csv continues on, I want to create a new csv file from this that would expand the CIDR to all its possible IPs, but still have the proper location tied to it.
| IPs | Location |
| -------- | ------- |
| y.y.y.y | OFFICE |
| y.y.y.y | OFFICE |
| y.y.y.y | OFFICE |
| y.y.y.y | OFFICE |
| y.y.y.y | OFFICE |
and so on
CodePudding user response:
One way of doing it is using netaddr module & apply to CIDR column
>>> import netaddr
>>> data = {
'CIDR': ['10.0.0.0/29', '10.1.2.0/30', '192.168.1.0/29', '172.16.0.0/29'],
'Location': [ 'OFFICE', 'DATACENTER', 'DATACENTER', 'DATACENTER']}
>>> df = pd.DataFrame(data)
>>> pd.concat([df,df.CIDR.apply(netaddr.IPNetwork).explode().rename('IP')], axis=1)
CIDR Location IP
0 10.0.0.0/29 OFFICE 10.0.0.0
0 10.0.0.0/29 OFFICE 10.0.0.1
0 10.0.0.0/29 OFFICE 10.0.0.2
0 10.0.0.0/29 OFFICE 10.0.0.3
0 10.0.0.0/29 OFFICE 10.0.0.4
0 10.0.0.0/29 OFFICE 10.0.0.5
0 10.0.0.0/29 OFFICE 10.0.0.6
0 10.0.0.0/29 OFFICE 10.0.0.7
1 10.1.2.0/30 DATACENTER 10.1.2.0
1 10.1.2.0/30 DATACENTER 10.1.2.1
1 10.1.2.0/30 DATACENTER 10.1.2.2
1 10.1.2.0/30 DATACENTER 10.1.2.3
2 192.168.1.0/29 DATACENTER 192.168.1.0
2 192.168.1.0/29 DATACENTER 192.168.1.1
2 192.168.1.0/29 DATACENTER 192.168.1.2
2 192.168.1.0/29 DATACENTER 192.168.1.3
2 192.168.1.0/29 DATACENTER 192.168.1.4
2 192.168.1.0/29 DATACENTER 192.168.1.5
2 192.168.1.0/29 DATACENTER 192.168.1.6
2 192.168.1.0/29 DATACENTER 192.168.1.7
3 172.16.0.0/29 DATACENTER 172.16.0.0
3 172.16.0.0/29 DATACENTER 172.16.0.1
3 172.16.0.0/29 DATACENTER 172.16.0.2
3 172.16.0.0/29 DATACENTER 172.16.0.3
3 172.16.0.0/29 DATACENTER 172.16.0.4
3 172.16.0.0/29 DATACENTER 172.16.0.5
3 172.16.0.0/29 DATACENTER 172.16.0.6
3 172.16.0.0/29 DATACENTER 172.16.0.7
CodePudding user response:
Assuming your DataFrame has valid CIDR you can combine ipaddress.IPv4Network
and pandas.DataFrame.explode
:
import ipaddress
df2 = (df.assign(CIDR=df['CIDR'].map(lambda x: list(ipaddress.IPv4Network(x))))
.explode('CIDR')
)
example input:
df = pd.DataFrame({'CIDR': ['192.168.1.0/24', '10.0.0.0/24'],
'Location': ['OFFICE', 'DATACENTER']})
output:
CIDR Location
0 192.168.1.0 OFFICE
0 192.168.1.1 OFFICE
0 192.168.1.2 OFFICE
0 192.168.1.3 OFFICE
0 192.168.1.4 OFFICE
.. ... ...
1 10.0.0.251 DATACENTER
1 10.0.0.252 DATACENTER
1 10.0.0.253 DATACENTER
1 10.0.0.254 DATACENTER
1 10.0.0.255 DATACENTER
[512 rows x 2 columns]