熊猫检查哪个子网IP地址属于

我有一个包含用户及其 IP 地址的 Pandas 数据框:


users_df = pd.DataFrame({'id': [1,2,3],

                         'ip': ['96.255.18.236','105.49.228.135','104.236.210.234']})


   id               ip

0   1    96.255.18.236

1   2   105.49.228.135

2   3  104.236.210.234

以及包含网络范围和相应地理名称 ID 的单独数据框:


geonames_df = pd.DataFrame({'network': ['96.255.18.0/24','105.49.224.0/19','104.236.128.0/17'],

                            'geoname': ['4360369.0','192950.0','5391959.0']})


     geoname           network

0  4360369.0    96.255.18.0/24

1   192950.0   105.49.224.0/19

2  5391959.0  104.236.128.0/17

对于每个用户,我需要针对所有网络检查他们的 ip,并提取相应的 geoname 并将其添加到users_df. 我想要这个作为输出:


   id               ip   geonames

0   1    96.255.18.236  4360369.0

1   2   105.49.228.135   192950.0

2   3  104.236.210.234  5391959.0

在这个例子中很简单,因为它们的顺序是正确的,只有 3 个例子。实际上,users_df有 4000 行,并且geonames_df有超过 300 万行


我目前正在使用这个:


import ipaddress


networks = []

for n in geonames_df['network']:

    networks.append(ipaddress.ip_network(n))


geonames = []


for idx, row in users_df.iterrows():

    ip_address = ipaddress.IPv4Address(row['ip'])


    for block in networks:

        if ip_address in block:

            geonames.append(str(geonames_df.loc[geonames_df['network'] == str(block), 'geoname'].item()))

            break


users_df['geonames'] = geonames

由于数据帧/列表上的嵌套循环,这非常慢。有没有更快的方法来利用 numpy/pandas?或者至少是某种比上述方法更快的方法?


有一个类似的问题(如何在 python 2.x 中检查 ip 是否在网络中?),但是 1)它不涉及 pandas/numpy,2)我想针对多个网络检查多个 IP ,以及 3 ) 得票最高的答案无法避免嵌套循环,这就是我性能缓慢的原因


肥皂起泡泡
浏览 122回答 2
2回答
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python