pandas合并彼此不到20秒的交互

时间:2018-05-08 12:54:34

标签: python pandas merge

我正在尝试合并我的交互数据集,如果它们相互发生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.

1 个答案:

答案 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