如何在kdb+q中按连续5秒间隔计算行的streak count
计算连续行时间差≤5秒的连续计数(Streak Count)
问题背景
现有KDB+数据表:
t:([] time:2023.07.10D01:30:23.595000000 2023.07.10D01:31:06.843000000 2023.07.10D01:31:08.482000000 2023.07.10D01:31:10.123000000 2023.07.10D01:31:11.267000000 2023.07.10D01:31:12.348000000;flag:111111b;Id:6#1234)
需实现连续行时间差≤5秒的连续计数(streakCount),规则如下:
- 首条记录计数为1
- 当前行与前一行时间差≤5秒时,计数递增1
- 时间差>5秒时,计数重置为1
尝试过wj1函数,但该方法仅检查时间桶内首尾行的5秒差,不符合需求。期望输出如下:
|time |flag |Id | streakCount| |2023.07.10D01:30:23.595000000 |1 |1234| 1 //首条记录| |2023.07.10D01:31:06.843000000 |1 |1234| 1 //与前一条差>5秒| |2023.07.10D01:31:08.482000000 |1 |1234| 2 //与前一条差<5秒| |2023.07.10D01:31:10.123000000 |1 |1234| 3 //与前一条差<5秒| |2023.07.10D01:31:11.267000000 |1 |1234| 4 //与前一条差<5秒| |2023.07.10D01:31:12.348000000 |1 |1234| 5 //与前一条差<5秒|
解决方案
利用KDB+的diff、scan函数可以高效实现需求:
分步实现
// 计算相邻行的时间差,首行补0(不影响后续判断) timeDiff: 0, diff t.time; // 生成重置标记:时间差>5秒时标记为1(需要重置计数),否则为0 resetFlag: timeDiff > 5; // 使用scan累加计数,遇到重置标记时从1重新开始 streakCount: 1 + scan {x + not y} 0, resetFlag[1:]; // 将计数列添加到原表 result: t, `streakCount!streakCount;
简洁链式写法
result: t, `streakCount!1 + scan {x + not y} 0, (0,diff t.time)[1:] > 5;
执行上述代码后,result表即可得到符合预期的输出。
内容的提问来源于stack exchange,提问作者VUM
相关产品推荐
相关产品推荐

