Python 在2个数据帧上使用NetAddress查看ip列是否落在具有布尔结果的cidr列中
我正在使用netaddr python库。我有两个数据帧,一个是IP范围,我将其转换为CIDR表示法,另一个是IP地址,我想看看它们是否属于任何范围 创建范围数据帧:Python 在2个数据帧上使用NetAddress查看ip列是否落在具有布尔结果的cidr列中,python,pandas,numpy,dataframe,networking,Python,Pandas,Numpy,Dataframe,Networking,我正在使用netaddr python库。我有两个数据帧,一个是IP范围,我将其转换为CIDR表示法,另一个是IP地址,我想看看它们是否属于任何范围 创建范围数据帧: import pandas as pd import netaddr from netaddr import * a = {'StartAddress': ['65.14.88.64', '148.77.37.88', '65.14.41.128', '65.14.40.0'], 'EndAddress': ['65.14.8
import pandas as pd
import netaddr
from netaddr import *
a = {'StartAddress': ['65.14.88.64', '148.77.37.88', '65.14.41.128', '65.14.40.0'],
'EndAddress': ['65.14.88.95', '148.77.37.95','65.14.41.135', '65.14.40.255']}
df1 = pd.DataFrame(data=a)
#Convert range to netaddr cidr format
def rangetocidr(row):
return netaddr.iprange_to_cidrs(row.StartAddress, row.EndAddress)
df1["CIDR"] = df1.apply(rangetocidr, axis=1)
df1
StartAddress EndAddress CIDR
0 65.14.88.64 65.14.88.95 [65.14.88.64/27]
1 148.77.37.88 148.77.37.95 [148.77.37.88/29]
2 65.14.41.128 65.14.41.135 [65.14.41.128/29]
3 65.14.40.0 65.14.40.255 [65.14.40.0/24]
df1["CIDR"].iloc[0]
[IPNetwork('65.14.88.64/27')]
创建IP数据帧:
b = {'IP': ['65.13.88.64', '148.65.37.88','65.14.88.65','148.77.37.93','66.15.41.132']}
df2 = pd.DataFrame(data=b)
#Convert ip to netaddr format
def iptonetaddrformat (row):
return netaddr.IPAddress(row.IP)
df2["IP_Format"] = df2.apply(iptonetaddrformat, axis=1)
df2
IP IP_Format
0 65.13.88.64 65.13.88.64
1 148.65.37.88 148.65.37.88
2 65.14.88.65 65.14.88.65
3 148.77.37.93 148.77.37.93
4 66.15.41.132 66.15.41.132
df2["IP_Format"].iloc[0]
IPAddress('65.13.88.64')
如果IP位于df1
的cidr块中,我希望在df2
中添加一列。所以它看起来像:
df2
IP IP_Format IN_CIDR
0 65.13.88.64 65.13.88.64 False
1 148.65.37.88 148.65.37.88 False
2 65.14.88.65 65.14.88.65 True
3 148.77.37.93 148.77.37.93 True
4 66.15.41.132 66.15.41.132 False
我更愿意只使用2个数据帧中的列来执行此操作,但我尝试过将列转换为列表并使用以下方法,但这似乎不起作用:
df2list = repr(df2[['IP_Format']])
df1list = df[['CIDR']]
def ipincidr (row):
return netaddr.largest_matching_cidr(df2list, df1list)
df2['INRANGE'] = df2.apply(ipincidr, axis=1)
下面的解决方案基于这样的假设,即只有第四组IP发生变化,前三组保持不变,如所述
#将IP拆分为两部分uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。
#对来自df2的IP以及来自df1的开始列和结束列执行此操作
ip=pd.DataFrame(df2.ip.str.rsplit('.',1,expand=True))
ip.columns=['ip_init','ip_last']
start=pd.DataFrame(df1.StartAddress.str.rsplit('.',1,expand=True))
start.columns=['start\u init','start\u last']
end=pd.DataFrame(df1.EndAddress.str.rsplit('.',1,expand=True))
end.columns=['end\u init','end\u last']
df=pd.concat([ip,开始,结束],轴=1)
#检查任何IP是否属于任何给定的块,如果是,请记下它们的索引
索引=[]
对于idx,枚举中的val(df.itertuples()):
对于范围内的i(df.start_init.count()):
如果df.loc[idx,'IP_init']==df.loc[i,'start_init']:
如果df.loc[idx,'IP_last']>=df.loc[i,'start_last']
和df.loc[idx,'IP_last']通常,你能解释一下IP什么时候属于CIDR的范围吗?举个例子,比如说65.13.88.64
,你介意澄清一下65.13.88.64
结果如何True
,因为我没有看到\uuuuuuu13的对应CIDR。这是一个很好的问题@meW我纠正了它的错误答案@meW这起作用了完美,即使我添加了更多的范围和IP的它仍然是准确的!我曾经学习过中央通讯社,但失去了所有的记忆。哈哈。享受吧!
# Splitting IP into 2 parts __.__.__ and __.
# Doing this for IP from df2 along with Start and End columns from df1
ip = pd.DataFrame(df2.IP.str.rsplit('.', 1, expand=True))
ip.columns = ['IP_init', 'IP_last']
start = pd.DataFrame(df1.StartAddress.str.rsplit('.', 1, expand=True))
start.columns = ['start_init', 'start_last']
end = pd.DataFrame(df1.EndAddress.str.rsplit('.', 1, expand=True))
end.columns = ['end_init', 'end_last']
df = pd.concat([ip, start, end], axis=1)
# Checking if any IP belongs to any of the given blocks, if yes, note their index
index = []
for idx, val in enumerate(df.itertuples()):
for i in range(df.start_init.count()):
if df.loc[idx, 'IP_init'] == df.loc[i, 'start_init']:
if df.loc[idx, 'IP_last'] >= df.loc[i, 'start_last']
and df.loc[idx, 'IP_last'] <= df.loc[i, 'end_last']:
index.append(idx)
break
# Creating column IN_CIDR and marking True against the row which exists in IP block
df2['IN_CIDR'] = False
df2.loc[index, 'IN_CIDR'] = True
df2
IP IP_Format IN_CIDR
0 65.13.88.64 65.13.88.64 False
1 148.65.37.88 148.65.37.88 False
2 65.14.88.65 65.14.88.65 True
3 148.77.37.93 148.77.37.93 True
4 66.15.41.132 66.15.41.132 False