【发布时间】:2021-10-04 05:56:17
【问题描述】:
希望有人能帮我解决这个问题。
我有一个结构如下的 csv 文件:
如果事件从匹配的第一个事件开始以 10 分钟的阈值出现,我正在尝试根据 message、name、userID 对事件进行分组。
我期望从 csv 得到的输出是只看到 3 行,因为第二行和第三行(因为它们在 10 分钟的阈值内并且消息、名称和 ID 相同,它们应该被分组)并且有一个额外的列名称 event_count 报告该事件发生了多少次。像这样
我开始处理这个问题,我的脚本如下所示:
import csv
import pandas as pd
# 0. sort data by timestamp if not already sorted
file_csv = 'test.csv'
f = pd.read_csv(file_csv)
f['@timestamp'] = pd.to_datetime(f['@timestamp'])
f = f.sort_values('@timestamp')
# lazy groupby
groups = f.groupby(['message','name','userID'])
# 1. compute the time differences `timediff` and compare to threshold
f['timediff'] = groups['@timestamp'].diff() < pd.Timedelta(minutes=10)
# 2. find the blocks with cumsum
f['event_count'] = groups['timediff'].cumsum()
# 3. groupby the blocks
out = (f.groupby(['message','name', 'userID'])
.agg({'@timestamp':'first', 'timediff':'count'})
)
keep_col = ['@timestamp', 'message', 'name', 'userID', 'event_count']
new_f = f[keep_col]
new_f.to_csv("aggregationtest.csv", index=False)
但是聚合是完全错误的,因为即使它们没有落在 10 分钟的阈值内,也会将所有事件分组在一起。
如果有人可以帮助我理解问题,我真的很难理解我做错了什么
更新:
经过一些测试,我设法得到了更接近我期望的输出,但仍然是错误的。
我对 out 变量做了一些更新,如下所示
out = (f.groupby(['message','name', 'userID', 'timediff']).agg({'@timestamp':'first','message': 'unique','name': 'unique', 'userID': 'unique', 'timediff': 'count'}))
这段代码现在产生如下输出:
但即使它现在分组,计数也是错误的。拥有这个 csv 文件
@timestamp,message,name,userID
2021-07-13 21:36:18,Failed to download file,Failed to download file,admin
2021-07-14 03:46:16,Successful Logon for user "user1",Logon Attempt,1
2021-07-14 03:51:16,Successful Logon for user "user1",Logon Attempt,1
2021-07-14 03:54:16,Successful Logon for user "user1",Logon Attempt,1
2021-07-14 04:55:16,Successful Logon for user "user1",Logon Attempt,1
我希望有以下 event_count
1
3
1
但我变得不一样了。
【问题讨论】:
-
请以纯文本形式发布您的 csv 文件样本,以便我们重现您的问题。
-
非常感谢您的回复。我用纯文本的 csv 更新了我的帖子。再次感谢您
标签: python-3.x pandas dataframe csv