I'm trying to check one list of IP addresses against another list of Networks that it could belong to. The lengths:
len(IP_addresses_list) = 31995
len(Network_list) = 54099
big_dict = {}
for ip in IP_addresses_list:
address_and_networks = self.is_subnet_of(ip, Network_list)
big_dict.update(address_and_networks)
df = pd.DataFrame.from_dict(big_dict, orient="index")
And the loop is verifying whether it belongs to the network by:
def is_subnet_of(self, ip, Network_list):
address_and_networks = {}
address = ipaddress.ip_address(ip)
for net in Network_list:
network = ipaddress.ip_network(net)
res = network.supernet_of(ipaddress.ip_network(f"{address}/{address.max_prefixlen}"))
if res:
if ip in address_and_networks:
address_and_networks[ip].append(net)
else:
address_and_networks[ip] = [net]
return address_and_networks
The address_and_networks dict may look like:
{
"xxx.xxx.xxx.xxx": ["xxx.xxx.xxx.xxx/24", "xxx.xxx.xxx.xxx/23"],
"yyy.yyy.yyy.yyy": ["yyy.yyy.yyy.yyy/24", "yyy.yyy.yyy.yyy/23"]
}
This method is currently painstakingly slow, so slow it's just not feasible to use. I'd like to accelerate this somehow, perhaps by dumping the original lists (IP_addresses_list, Network_list) into a dataframe then perform some sweeping execution on the dataframe, by applying the is_subnet_of method (maybe something like dataframe.select or dataframe.apply). Any idea how I can speed this up?
EDIT
I streamlined the code further, but I'm still resorting to looping over the dataframes:
df = pd.DataFrame({"IP_Address": ip_s.map(ipaddress.ip_address),
"Network": net_s.map(ipaddress.ip_network),
"Associated": np.nan})
for i, address in df["IP_Address"].iteritems():
if address != address:
continue
net_list = []
for j, network in df["Network"].iteritems():
if network.supernet_of(ipaddress.ip_network(f"{address}/{address.max_prefixlen}")):
net_list.append(str(network))
df.loc[i, "Associated"] = net_list
Example data:
Addresses = ['172.16.56.40','172.16.16.16']
Networks = ['172.16.56.0/24', '172.16.56.32/27']