python - 如何在 GroupBy 中满足逻辑条件的 "collapse"行

标签 python pandas

我有一个如下所示的数据框:

In [134]: df
Out[134]: 
            A                               ID3            DATETIME
0  BRT-481028  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 13:43:27
1  BRT-481054  4a57ed0b02fa357bf3c51cc9460e8d96 2014-10-08 14:26:19
2  BRT-481076  1a682034f8cbc542f36e46215635da9a 2014-10-08 14:29:01
3  BRT-481023  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:39:34
4  BRT-481023  f88g8d7sds799asde83b2523944p9r78 2014-10-08 18:40:18
5  BRT-481033  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:44:30
6  BRT-481032  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:46:00
7  BRT-481037  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:52:15
8  BRT-481046  db959faf023e5df33032db4808882f0c 2014-10-08 18:59:59
9  BRT-481053  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 19:17:48
10 BRT-481065  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 19:21:38

每一行代表由用户触发的事件 - 为本示例通过中的值进行标识df['ID3']。每个事件都有更多的属性,但我已经剪掉了其他所有内容。

对于我想要构建的内容,我只需要为每个用户和每 5 分钟滚动周期保留一个事件。所有其他事件,在同一时间段内,由同一用户执行,都只是噪音,会干扰进一步执行的其他逻辑,因此应被丢弃。因此,我需要为每个用户最多保留一条记录和 5 分钟滚动周期。更具体地说,我需要保留同一时间段内任意数量的记录中的最新记录。

所需的输出如下所示:

            A                               ID3            DATETIME
0  BRT-481028  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 13:43:27
1  BRT-481054  4a57ed0b02fa357bf3c51cc9460e8d96 2014-10-08 14:26:19
2  BRT-481076  1a682034f8cbc542f36e46215635da9a 2014-10-08 14:29:01
4  BRT-481023  f88g8d7sds799asde83b2523944p9r78 2014-10-08 18:40:18
6  BRT-481032  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:46:00
7  BRT-481037  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:52:15
8  BRT-481046  db959faf023e5df33032db4808882f0c 2014-10-08 18:59:59
10 BRT-481065  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 19:21:38

上面的行[3,5,9] 上的记录已被丢弃,因为它们符合上述条件。另外,请注意 3 行和 6 行之间的时间间隔大于 5 分钟,但是,由于同时创建了记录 5滚动窗口导致这些记录被丢弃。

另请注意,第 4 行的记录保持不变,因为它与不同的用户关联。

编辑

现在我已经更进一步了,我使用了 diff()groupby() 来查看达到此目的:

In [309]: df['diff'] = df.sort_values(by='DATETIME').groupby('ID3')['DATETIME'].transform(lambda x: x.diff())

In [310]: df
Out[310]: 
             A                               ID3            DATETIME  \
0   BRT-481028  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 13:43:27   
1   BRT-481054  4a57ed0b02fa357bf3c51cc9460e8d96 2014-10-08 14:26:19   
2   BRT-481076  1a682034f8cbc542f36e46215635da9a 2014-10-08 14:29:01   
3   BRT-481023  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:39:34   
4   BRT-481023  f88g8d7sds799asde83b2523944p9r78 2014-10-08 18:40:18   
5   BRT-481033  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:44:30   
6   BRT-481032  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:46:00   
7   BRT-481037  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 18:52:15   
8   BRT-481046  db959faf023e5df33032db4808882f0c 2014-10-08 18:59:59   
9   BRT-481053  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 19:17:48   
10  BRT-481065  b76cd912ffcb97e21de83b252391b2a0 2014-10-08 19:21:38   

                  diff  
0                  NaT  
1                  NaT  
2                  NaT  
3  1970-01-01 04:56:07  
4                  NaT  
5  1970-01-01 00:04:56  
6  1970-01-01 00:01:30  
7  1970-01-01 00:06:15  
8                  NaT  
9  1970-01-01 00:25:33  
10 1970-01-01 00:03:50

我似乎无法获得差异的秒数。我尝试过:

>> findTheDiff = lambda x: x.diff().astype(np.int64)

代替上面的lambda,但这并没有多大区别。

我希望将 '1970-01-01 00:01:30' 变为 '90'!

感谢您的帮助!

最佳答案

diff 返回具有 seconds 属性的 Timedelta 对象。

解决方案(也许)

findTheDiff = lambda x: x.diff().seconds

关于python - 如何在 GroupBy 中满足逻辑条件的 "collapse"行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36941505/

相关文章:

python - 按组划分的 Pandas 时间累计和

python - Pandas Python-read_csv 未读取每一行的完整数据

python - 然后 Groupby 检查行匹配并计算该值的并发实例数

python - 使用 Pandas 写入文件会产生空行

python - 将 SRE_Match 对象转换为字符串

python - PyvMomi 创建新的虚拟机

python - 如何在numpy中优化此图像迭代?

python - 在 Django 2.0 上使用过滤器

python - 对 plotly 在线/离线/袖扣和不同版本感到困惑

python - 将数组转换为 Pandas 数据框列