python - pandas 合并彼此相距不到 20 秒的交互
问题描述
如果它们彼此相距 0-20 秒,我正在尝试合并我的交互数据集。
我的 CSV 文件的第一行:
Source, Target, time_start, time_end, total_time
0x597E5627, 0x3C992634, 1532, 1583, 51
0x597E5627, 0x3C992634, 1627, 1652, 25
0x597E5627, 0x3C992634, 1755, 2492, 737
0x597E5627, 0x3C3A21AD, 2649, 2681, 32
0x597E5627, 0x3C3A21AD, 3028, 3058, 30
0x597E5627, 0x3C3A21AD, 3071, 3094, 23
输出应该是什么(注意最后一行):
Source, Target, time_start, time_end, total_time
0x597E5627, 0x3C992634, 1532, 1583, 51
0x597E5627, 0x3C992634, 1627, 1652, 25
0x597E5627, 0x3C992634, 1755, 2492, 737
0x597E5627, 0x3C3A21AD, 2649, 2681, 32
0x597E5627, 0x3C3A21AD, 3028, 3094, 53
因为最后一次交互是 time_start 3071- time_end 3058 = 13 秒,所以我认为这仍然是 1 次对话。
现在代码似乎工作。我成功地找到了需要合并的案例,并制作了一个累积列表,列出了我的数据中发生了哪些交互组,但我的输出只显示了秒数,并过滤掉了我的芯片名称。
import pandas as pd
df = pd.read_csv('filter20seconds.csv')
start_end_differences = df.time_start - df.time_end.shift(1)
threshold_selector = start_end_differences > 20
groups = threshold_selector.cumsum()
new = df.groupby(groups).agg({'time_start':min, 'time_end':max,
'total_time':sum})
print(new)
有没有人发现我做错了什么,源和目标的名称消失了?
我现在的输出:
time_start time_end total_time
0 1532 1583 51
1 1627 1652 25
2 1755 2492 737
3 2649 2681 32
4 3028 3094 53
------------- 出现问题 ----
Source, Target, time_start, time_end, total_time
0x6979EF0C, 0x300C163D, 6049, 6083, 34
0x6979EF0C, 0x300C163D, 6125, 6236, 111
0x15697F98, 0x3C3A21AD, 1855, 1875, 20
0x15697F98, 0x064F5882, 2749, 2776, 27
0x15697F98, 0x064F5882, 3040, 3078, 38
在这里,计算为 1855-6236 的行将被合并,因为它低于 20。
解决方案
假设您构建一个以索引为节点的图
import networkx as nx
import itertools
G = nx.Graph()
G.add_nodes_from(df.index)
将距离小于 20 的所有行对添加屁股边缘:
G.add_edges_from(
[(r1[0], r2[0]) for (r1, r2) in itertools.product(df.iterrows(), df.iterrows()) if r1[0] < r2[0] and r1[1]['time_end'] + 20 > r2[1]['time_start']]
)
现在找到所有连接组件:
groups = dict(itertools.chain.from_iterable([[(ee, i) for ee in e] for (i, e) in enumerate(nx.connected_components(G))]))
>>> df.index.map(lambda j: groups[j])
Int64Index([0, 1, 2, 3, 4, 4], dtype='int64')
请注意,4 和 5 已被正确识别为属于同一组。
此时,您只需要以groups
通常的方式进行分组。例如,对于开始时间:
>>> df.time_start.groupby(df.index.map(lambda j: groups[j])).min()
0 1532
1 1627
2 1755
3 2649
4 3028
Name: time_start, dtype: int64
推荐阅读
- winforms - iTextSharp 无法正确读取 pdf 中的字段
- javascript - 在 Javascript 文本中写入 HTML 标签
- html - 当我两次单击某个链接时,我的网站崩溃了
- node.js - 使用 Admin SDK 将文件上传到 Firebase 存储
- node.js - 使用 API 网关响应调用 Node.js PUT Lambda 函数
- java - CDI 2.0,Java SE - 在weld-se-shaded 3.0.5.Final 中未调用条件观察者方法
- javascript - Photoshop:循环直到达到所需的值
- tensorflow - 使用 BERT 进行下一句预测
- firebase - 如何在我的 Firebase 安全规则中添加“.indexOn”?
- amazon-web-services - 如何创建 S3 存储桶以避免名称冲突