Pandas将列表值(1、2、3)转换为范围(13)?

2024-04-19 08:17:54 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有简单的方法可以将数字的范围(1、2、3、4、5)转换成易于阅读的范围(1-5)

我正在使用IP/端口组合,并试图列出单个IP上看到的端口范围,其中单个IP上可能有50000多个端口,但我希望能够看到类似于[1-50000]的内容,而不是列出每个端口

    IP  Port
0   1.1.1.1     1
1   1.1.1.1     2
2   1.1.1.1     3
3   1.1.1.1     4
4   1.1.1.1     5
5   1.1.1.1     6
6   1.1.1.1     7
7   1.1.1.1     8
8   1.1.1.1     9
9   1.1.1.1    10
10  1.1.1.1    11
11  1.1.1.1    12
12  1.1.1.1    13
13  1.1.1.1    14
14  1.1.1.2    15
15  1.1.1.2    16
16  1.1.1.2    18
17  1.1.1.2    20
18  1.1.1.2    22
19  1.1.1.2    27
20  1.1.1.3    40
21  1.1.1.3    41
22  1.1.1.3    42
23  1.1.1.3    43
24  1.1.1.3    44
25  1.1.1.3    45
26  1.1.1.3    46
27  1.1.1.3    47

//代码//

df.groupby('IP')['Port'].apply(list)

//结果//

1.1.1.1    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]  
1.1.1.2                           [15, 16, 18, 20, 22, 27]  
1.1.1.3                   [40, 41, 42, 43, 44, 45, 46, 47]  

//所需结果//

1.1.1.1                     [1-14]  
1.1.1.2    [15-16, 18, 20, 22, 27]  
1.1.1.3                    [40-47]

1条回答
网友
1楼 · 发布于 2024-04-19 08:17:54

这就是我要做的:

s = df.groupby('IP').Port.diff()
new_df = (df.groupby(['IP', s.ne(1).groupby(df['IP']).cumsum()])
            .Port.agg(['min','max','count'])
            .reset_index('Port', drop=True)
         )
new_df['out'] = np.where(new_df['count']==1, 
                         new_df['min'], 
                         new_df[['min','max']].astype(str).agg('-'.join, axis=1))
new_df.groupby('IP')['out'].apply(list)

输出:

IP
1.1.1.1                     [1-14]
1.1.1.2    [15-16, 18, 20, 22, 27]
1.1.1.3                    [40-47]
Name: out, dtype: object

相关问题 更多 >