基于目标端口值聚合源字节数:如何通过agg实现条件求和?
解决方法:将指定端口的source_bytes求和并生成独立列
嘿,我来帮你搞定这个需求!你想要把destination_port为80的source_bytes求和后,放到一个名为source_bytes_port_80的独立列里,其实有几种灵活的实现方式,既可以满足你想用自定义函数配合agg的思路,也有更直接的简化方案:
方法一:直接生成全局总和列(最简单)
如果你需要的是整个数据集里所有port=80的source_bytes总和,并把这个值放到每一行的新列中,直接计算后赋值就可以:
import pandas as pd # 先构造你的测试DataFrame data = { 'date': ['2020-11-13 13:57:51', '2020-11-13 13:57:51', '2020-11-13 13:57:52', '2020-11-13 13:59:53', '2020-11-13 13:59:54'], 'source_ip': ['192.168.1.1', '192.168.1.2', '10.0.0.1', '192.168.1.1', '192.168.1.1'], 'destination_ip': ['10.0.0.1', '10.0.0.1', '192.168.1.1', '192.168.1.2', '192.168.1.2'], 'source_bytes': [5, 1, 2, 3, 3], 'destination_port': [80, 2200, 80, 443, 1100] } df = pd.DataFrame(data) # 计算port=80的source_bytes总和 total_port80 = df.loc[df['destination_port'] == 80, 'source_bytes'].sum() # 赋值给新列 df['source_bytes_port_80'] = total_port80
执行后,新列的每一行都会显示总和7(5+2)。
方法二:按维度分组聚合(保留原始行)
如果需要按某个维度(比如source_ip、date)分别计算每组内port=80的总和,用transform可以直接把聚合结果映射回原始行:
# 按source_ip分组,计算每个IP对应的port=80的source_bytes总和 df['source_bytes_port_80'] = df.groupby('source_ip')['source_bytes'].transform( lambda x: x[df.loc[x.index, 'destination_port'] == 80].sum() )
结果里,192.168.1.1的行新列值为5,10.0.0.1的行值为2,其他IP的行值为0。
方法三:实现你想用的自定义函数+agg思路
如果你坚持要用自定义函数配合agg,可以这样写——注意要通过索引关联destination_port列来做条件判断:
def sum_of_port(x, target_port): # x是source_bytes的Series,通过索引匹配原DataFrame的destination_port mask = df.loc[x.index, 'destination_port'] == target_port return x[mask].sum() # 示例:按date分组聚合,生成每组的port80总和 grouped_result = df.groupby('date').agg( source_bytes_port_80=('source_bytes', lambda x: sum_of_port(x, 80)) ).reset_index() # 把聚合结果合并回原DataFrame df = df.merge(grouped_result, on='date', how='left')
这样就能得到每个日期下port=80的source_bytes总和,并对应到原始行中。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

