我正在尝试合并我的交互数据集,如果它们相互发生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.
答案 0 :(得分:2)
假设您构建一个索引为节点
的图形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