猿问

如果布尔结果为真,熊猫将返回 CIDR

我正在使用几个熊猫数据框。df1 有 IP 地址范围,df2 有 IP 地址。此代码使用布尔结果正确标记 df 列中的任何 IP 是否与 df 列中的任何 CIDR 匹配。我遇到了获取 CIDR 范围而不是返回布尔结果(如果为真)的问题。


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', '208.252.49.240','12.9.27.48','107.135.41.16','47.44.167.240'],

 'EndAddress': ['65.14.88.95', '148.77.37.95','65.14.41.135','65.14.40.255', '208.252.49.247','12.9.27.63','107.135.41.23','47.44.167.247']}


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["CIDR"].iloc[0]

创建ip数据帧


b = {'IP': ['65.13.88.64','148.65.37.88','65.14.88.65','148.77.37.93','66.15.41.132', '208.252.49.247','208.252.49.248','12.9.27.49']}

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_Format"].iloc[0]


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)


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


df2['IN_CIDR'] = False


df2.loc[index, 'IN_CIDR'] = True


我试过,df2.loc[index, 'IN_CIDR'] = df1.loc[index,'CIDR']但这只是给了我索引位置 df1 的 CIDR,而不是将它与 CIDR 范围内的 ip 匹配。


动漫人物
浏览 168回答 1
1回答

翻过高山走不出你

我正在使用这种方式:a = {'StartAddress': ['65.14.88.64', '148.77.37.88', '65.14.41.128', '65.14.40.0', '208.252.49.240', '12.9.27.48',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '107.135.41.16', '47.44.167.240'],&nbsp; &nbsp; &nbsp;'EndAddress': ['65.14.88.95', '148.77.37.95', '65.14.41.135', '65.14.40.255', '208.252.49.247', '12.9.27.63',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '107.135.41.23', '47.44.167.247']}df1 = pd.DataFrame(data=a)# Convert range to netaddr cidr formatdef rangetocidr(row):&nbsp; &nbsp; return netaddr.iprange_to_cidrs(row.StartAddress, row.EndAddress)df1["CIDR"] = df1.apply(rangetocidr, axis=1)b = {'IP': ['65.13.88.64', '148.65.37.88', '65.14.88.65', '148.77.37.93', '66.15.41.132', '208.252.49.247', '208.252.49.248', '12.9.27.49']}df2 = pd.DataFrame(data=b)# Convert ip to netaddr formatdef iptonetaddrformat(row):&nbsp; &nbsp; return netaddr.IPAddress(row.IP)df2["IP_Format"] = df2.apply(iptonetaddrformat, axis=1)df2['IN_CIDR'] = Falsefor i, row in df2.iterrows():&nbsp; &nbsp; ip = row['IP']&nbsp; &nbsp; for j, r in df1.iterrows():&nbsp; &nbsp; &nbsp; &nbsp; subnet = str(r['CIDR'][0])&nbsp; &nbsp; &nbsp; &nbsp; if ip_in_subnetwork(ip, subnet):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; df2.loc[i, 'IN_CIDR'] = '['+ subnet + ']'print(df2)输出:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IP&nbsp; &nbsp; &nbsp; &nbsp;IP_Format&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IN_CIDR0&nbsp; &nbsp; &nbsp;65.13.88.64&nbsp; &nbsp; &nbsp;65.13.88.64&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;False1&nbsp; &nbsp; 148.65.37.88&nbsp; &nbsp; 148.65.37.88&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;False2&nbsp; &nbsp; &nbsp;65.14.88.65&nbsp; &nbsp; &nbsp;65.14.88.65&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [65.14.88.64/27]3&nbsp; &nbsp; 148.77.37.93&nbsp; &nbsp; 148.77.37.93&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[148.77.37.88/29]4&nbsp; &nbsp; 66.15.41.132&nbsp; &nbsp; 66.15.41.132&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;False5&nbsp; 208.252.49.247&nbsp; 208.252.49.247&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[208.252.49.240/29]6&nbsp; 208.252.49.248&nbsp; 208.252.49.248&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;False7&nbsp; &nbsp; &nbsp; 12.9.27.49&nbsp; &nbsp; &nbsp; 12.9.27.49&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[12.9.27.48/28]这是我调用的函数以了解 IP 是否在子网中:import netaddr as netaddrimport socketimport binasciidef ip_in_subnetwork(ip_address, subnetwork):&nbsp; &nbsp; """&nbsp; &nbsp; Returns True if the given IP address belongs to the&nbsp; &nbsp; subnetwork expressed in CIDR notation, otherwise False.&nbsp; &nbsp; Both parameters are strings.&nbsp; &nbsp; Both IPv4 addresses/subnetworks (e.g. "192.168.1.1"&nbsp; &nbsp; and "192.168.1.0/24") and IPv6 addresses/subnetworks (e.g.&nbsp; &nbsp; "2a02:a448:ddb0::" and "2a02:a448:ddb0::/44") are accepted.&nbsp; &nbsp; """&nbsp; &nbsp; (ip_integer, version1) = ip_to_integer(ip_address)&nbsp; &nbsp; (ip_lower, ip_upper, version2) = subnetwork_to_ip_range(subnetwork)&nbsp; &nbsp; if version1 != version2:&nbsp; &nbsp; &nbsp; &nbsp; raise ValueError("incompatible IP versions")&nbsp; &nbsp; return (ip_lower <= ip_integer <= ip_upper)def ip_to_integer(ip_address):&nbsp; &nbsp; """&nbsp; &nbsp; Converts an IP address expressed as a string to its&nbsp; &nbsp; representation as an integer value and returns a tuple&nbsp; &nbsp; (ip_integer, version), with version being the IP version&nbsp; &nbsp; (either 4 or 6).&nbsp; &nbsp; Both IPv4 addresses (e.g. "192.168.1.1") and IPv6 addresses&nbsp; &nbsp; (e.g. "2a02:a448:ddb0::") are accepted.&nbsp; &nbsp; """&nbsp; &nbsp; # try parsing the IP address first as IPv4, then as IPv6&nbsp; &nbsp; for version in (socket.AF_INET, socket.AF_INET6):&nbsp; &nbsp; &nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_hex = socket.inet_pton(version, ip_address)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_integer = int(binascii.hexlify(ip_hex), 16)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (ip_integer, 4 if version == socket.AF_INET else 6)&nbsp; &nbsp; &nbsp; &nbsp; except:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pass&nbsp; &nbsp; raise ValueError("invalid IP address")def subnetwork_to_ip_range(subnetwork):&nbsp; &nbsp; """&nbsp; &nbsp; Returns a tuple (ip_lower, ip_upper, version) containing the&nbsp; &nbsp; integer values of the lower and upper IP addresses respectively&nbsp; &nbsp; in a subnetwork expressed in CIDR notation (as a string), with&nbsp; &nbsp; version being the subnetwork IP version (either 4 or 6).&nbsp; &nbsp; Both IPv4 subnetworks (e.g. "192.168.1.0/24") and IPv6&nbsp; &nbsp; subnetworks (e.g. "2a02:a448:ddb0::/44") are accepted.&nbsp; &nbsp; """&nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; fragments = subnetwork.split('/')&nbsp; &nbsp; &nbsp; &nbsp; network_prefix = fragments[0]&nbsp; &nbsp; &nbsp; &nbsp; netmask_len = int(fragments[1])&nbsp; &nbsp; &nbsp; &nbsp; # try parsing the subnetwork first as IPv4, then as IPv6&nbsp; &nbsp; &nbsp; &nbsp; for version in (socket.AF_INET, socket.AF_INET6):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_len = 32 if version == socket.AF_INET else 128&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suffix_mask = (1 << (ip_len - netmask_len)) - 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; netmask = ((1 << ip_len) - 1) - suffix_mask&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_hex = socket.inet_pton(version, network_prefix)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_lower = int(binascii.hexlify(ip_hex), 16) & netmask&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_upper = ip_lower + suffix_mask&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (ip_lower,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ip_upper,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 if version == socket.AF_INET else 6)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pass&nbsp; &nbsp; except:&nbsp; &nbsp; &nbsp; &nbsp; pass&nbsp; &nbsp; raise ValueError("invalid subnetwork")
随时随地看视频慕课网APP

相关分类

Python
我要回答