如何使用pandas统计每组源IP与响应IP组合的连接次数
Pandas统计源IP-响应IP连接数实现方案
问题背景
- 待处理的是网络流量JSON数据集,包含
uid、id.orig_h(源IP)、id.orig_p(源端口)、id.resp_h(响应IP)、id.resp_p(响应端口)等字段,单条数据格式如下:
"id.orig_h":"10.20.57.3","id.orig_p":59580,"id.resp_h":"10.10.2.22","id.resp_p":53,"proto":"udp","service":"dns",
- 目标:统计每一组唯一源IP与响应IP对应的连接次数,输出三列结构:
Orig IP、Resp IP、Number of times(count),期望输出示例:
Orig IP Resp IP Number of times(count) 1.2.3.4 3.4.5.6 30 4.2.1.3 1.2.3.4 122 4.4.4.4 192.1.3.4 79
现有代码问题
原有统计逻辑错误点:使用pd.concat([df['id.orig_h'], df['id.resp_h']]).value_counts()会把源IP列和响应IP列合并为单列后统计单个IP的全局出现次数,无法实现按「源IP+响应IP」二元组的分组统计,错误输出为单个IP的总出现次数:
10.20.57.3 7108 10.10.2.22 4238 10.10.2.21 2851 34.122.121.32 8
原有待修正的代码框架:
def readZeekFileJson(filename): df = pd.read_json(filename, lines=True) return df def readFile(filename): if is_exist_file(filename): df = pd.read_csv(filename, sep='\t') else: df = pd.DataFrame(columns=['max']) return df def get_stats(df): df_stats = pd.DataFrame(columns=statscols) df = pd.concat([df['id.orig_h'], df['id.resp_h']]).value_counts() # unique_values = pd.unique(column_values) print(df, count) #print(df['id.resp_h'].sort_values().unique()) return df_stats
正确实现代码
直接替换get_stats函数即可,核心是通过groupby按两个IP字段分组计数,再重命名列匹配输出要求:
import pandas as pd def get_stats(df): # 按源IP、响应IP二元组分组统计连接数 df_stats = ( df.groupby(['id.orig_h', 'id.resp_h'], as_index=False) .size() # 重命名列匹配输出格式要求 .rename(columns={ 'id.orig_h': 'Orig IP', 'id.resp_h': 'Resp IP', 'size': 'Number of times(count)' }) ) return df_stats
- 逻辑说明:
groupby(['id.orig_h', 'id.resp_h'])会将两个字段值完全一致的记录归为同一组,满足IP对去重统计的要求size()方法返回每组的记录条数,即对应IP对的连接次数- 如果需要按连接次数降序查看高频连接对,可增加排序逻辑:
def get_stats(df, sort_desc=False): df_stats = ( df.groupby(['id.orig_h', 'id.resp_h'], as_index=False) .size() .rename(columns={ 'id.orig_h': 'Orig IP', 'id.resp_h': 'Resp IP', 'size': 'Number of times(count)' }) ) if sort_desc: df_stats = df_stats.sort_values( 'Number of times(count)', ascending=False ).reset_index(drop=True) return df_stats
内容的提问来源于stack exchange,提问作者Bob Hes
相关产品推荐
相关产品推荐

