我有一个大型数据集,包含在网络中传播的对象的记录。数据集存储在pandas数据集中,大致如下所示:
Obj ID | Timestamp | x | y | link ID
-------|-----------|---|---|---------
123 | 506 |123|456| ab12
123 | 517 |129|436| ab12
123 | 519 |125|454| cd34
126 | 501 |123|426| gk77
126 | 505 |153|453| gk77
126 | 507 |129|856| bj88
126 | 508 |143|496| bj88
126 | 512 |125|427| gk77
126 | 515 |153|453| gk77
126 | 518 |127|256| ab12
数据框已按Obj ID
排序,属于某个对象的每个记录块已按时间排序(Timestamp
字段,以秒为单位)。具有相同Obj ID
和link ID
的两个连续行表示该链接的对象的开始和结束。该对象最终以链接结束,该链接由出现在对象记录末尾的单个链接ID表示。
这是所需的输出。将一个对象访问的开始记录和结束记录压缩到一个记录中。对于每个对象的结束链接,只需为StartTime
填写EndTime
。
Obj ID | StartTime | EndTime | link ID
-------|-----------|---------|---------
123 | 506 | 517 | ab12
123 | 519 | 519 | cd34
126 | 501 | 505 | gk77
126 | 507 | 508 | bj88
126 | 512 | 515 | gk77
126 | 518 | 518 | ab12
注意:
无法保证对象不会两次进入同一链接。但每次访问链接都需要单独记录。
由于数据集非常大,我实施的天真循环解决方案内存不足。
编辑:我编辑了数据集,以包含我在"笔记"的第一点中提到的情况。
答案 0 :(得分:2)
我们试试这个:
g =(df['link ID'] != df.shift().fillna(method='bfill')['link ID']).cumsum().rename('group')
df.groupby(['Obj ID','link ID',g])['Timestamp'].agg(['min','max']).reset_index().rename(columns={'min':'StartTime','max':'EndTime'}).drop('group',axis=1)
输出:
Obj ID link ID StartTime EndTime
0 123 ab12 506 517
1 123 cd34 519 519
2 126 ab12 518 518
3 126 bj88 507 508
4 126 gk77 501 505
5 126 gk77 512 515
答案 1 :(得分:0)
df.drop_duplicates(subset = ['Obj ID','link ID'],
keep='first').merge(x.drop_duplicates(subset = ['Obj ID','link ID'],
keep='last'), on= ['Obj ID','link ID'])