假设我有一个子网列表和它们的主子网
| ip | description | master subnet |
|------------|--------------------------------|---------------|
| 1.1.1.0/20 | master | / |
| 1.1.1.0/22 | subnet n-1, no further subnets | 1.1.1.0/20 |
| 1.1.2.0/24 | subnet n-1, further subnets | 1.1.1.0/20 |
| 1.1.3.0/29 | subnet n-2 | 1.1.2.0/24 |
| 1.1.3.1/29 | subnet n-2 | 1.1.2.0/24 |
我想知道每个主子网的已用/空闲 ips 数量。 我会通过查找主子网内的已知子网并从总 ips 中减去 ips 的数量来做到这一点。
但是,在我的数据中,主子网的子网“深度”不是恒定的。 1.1.1.0/20 由两个子网组成,一个 /22 和一个 /24。在 /22 中,所有 ip 都被视为正在使用(数据中没有其他子网)。但是在 /24 中,并不是所有的 ip 地址都被使用,而是只使用那些包含在后续行中的 ip 地址。
预期结果:
| ip | description | master subnet | total | used | free |
|------------|--------------------------------|---------------|-------|------|------|
| 1.1.1.0/20 | master | / | 4096 | 1040 | 3056 |
| 1.1.1.0/22 | subnet n-1, no further subnets | 1.1.1.0/20 | 1024 | 1024 | 0 |
| 1.1.2.0/24 | subnet n-1, further subnets | 1.1.1.0/20 | 256 | 16 | 240 |
| 1.1.3.0/29 | subnet n-2 | 1.1.2.0/24 | 8 | 8 | 0 |
| 1.1.3.1/29 | subnet n-2 | 1.1.2.0/24 | 8 | 8 | 0 |
常规
df.groupby('master subnet').sum()
不会考虑这种层次结构,而是将 /24 计为完全“使用”。
我数据中的其他示例转到 n-3 或 n-4,因此问题只是在其他级别上重复。
关于如何解决这个问题的任何线索?
可以先通过拆分前缀来计算
total
。然后 used
通过按 master subnet
分组然后映射 ip
。用 total
填充 NA 值然后减去。然后你必须在减去之前重新映射used
:
df['total'] = 2**(32 - df['ip'].str.split('/', expand=True)[1].astype(int))
subnet_total = df.groupby('master subnet')['total'].sum()
df['used'] = df['ip'].map(subnet_total).fillna(df['total']).astype(int)
subnet_used = df.groupby('master subnet')['used'].sum()
df.loc[df['ip'].isin(subnet_used.index),'used'] = df['ip'].map(subnet_used)
df['free'] = df['total'] - df['used']
print(df)
输出:
ip description master subnet total used free
0 1.1.1.0/20 master / 4096 1040 3056
1 1.1.1.0/22 subnet n-1, no further subnets 1.1.1.0/20 1024 1024 0
2 1.1.2.0/24 subnet n-1, further subnets 1.1.1.0/20 256 16 240
3 1.1.3.0/29 subnet n-2 1.1.2.0/24 8 8 0
4 1.1.3.1/29 subnet n-2 1.1.2.0/24 8 8 0