在 KDB 中根据每天设定的间隔数对每一行进行分类?

  • 本文关键字:分类 一行 KDB 每天 kdb
  • 更新时间 :
  • 英文 :


给定下表:

初始表:

shop | time    
-----------
A  | 1000
A  | 1100
B  | 1130
B  | 1131
C  | 1132
A  | 1133
A  | 1134
B  | 1230
C  | 1232
C  | 1400

结果表:

shop | time |  mark  Number of times a shop has appeared within an interval.
--------------------
1)  A  | 1000 |   0    [A = 1]
2)  A  | 1100 |   0    [A = 2]
3)  B  | 1130 |   0    [A = 2, B = 1]
4)  B  | 1131 |   0    [A = 2, B = 2]
5)  C  | 1132 |   0    [A = 2, B = 2, C = 1]
6)  A  | 1133 |   0    [A = 2, B = 2, C = 1]
7)  A  | 1134 |   1    [A = 3 (Mark cell), B = 2, C = 1]
8)  B  | 1230 |   1    [A = 1, B = 3 (Mark cell), C = 1]
9)  C  | 1232 |   0    [A = 1, B = 1, C = 2]
10)  C  | 1400 |   0    [A = 1, B = 1, C = 0]

哪里:

  • t= 1 小时。

  • n= 3。

对于固定间隔t,如果t内有n或更多事务,则将该行标记为 true1。否则标记为0

解释:

  • 第 1 行到第 2 行,At内进行两笔交易。

  • 第 3 行到第 4 行,Bt内进行两笔交易。

  • 第 5 行,C有它的第一个事务。

  • 第 6 行,A进行另一笔交易,但该单元格未标记为此事务与第一个事务之间的 - 间隔超过t(1000 -> 1133)。

  • 第 7 行,行标记为At(1100 -> 1133 -> 1134) 内有n事务。

  • 第 8 行,行标记为Bt内有n事务 (1130 -> 1131 -> 1230)

  • 第 9 行和第 10 行,C进行两笔交易,但由于间隔超过t(1132 -> 1232 ---> 1400) 而未标记

此外,这将每天刷新一次(YYYYMMDD格式中包含列DealDate)

从本质上讲,这模拟了每个商店的队列,其中推送到堆栈的每个项目将根据队列中的项目数量进行标记,每个超过间隔的项目都会弹出。

如何在 KDB 中仅使用 Q 完成此操作?日期和时间戳按降序排序。

您可以使用:

q)table:([]shop:`A`A`B`B`C`A`A`B`C`C; time:1000 1100 1130 1131 1132 1133 1134 1230 1232 1400)
q)t:100
q)n:3
q)update mark:t>=(t+1)^time-(n-1)xprev time by shop from table
shop time mark
--------------
A    1000 0
A    1100 0
B    1130 0
B    1131 0
C    1132 0
A    1133 0
A    1134 1
B    1230 1
C    1232 0
C    1400 0

这将计算每个单元格与其后面两行(time-(n-1)xprev time)的商店(by shop)之间的时间差。

然后,它用大于 t 的值填充空值,因为我们不想包含这些单元格 ((t+1)^)。

然后,它检查三者中最早的时间是否在当前时间的 1 小时内,将 1 分配给 1 这是真的 (t>=)。

这也可以通过包括by dealDate来刷新每个日期:

table:([]dealDate:(10#20190704),10#20190705;shop:20#`A`A`B`B`C`A`A`B`C`C; time:20#1000 1100 1130 1131 1132 1133 1134 1230 1232 1400)
q)update mark:t>=(t+1)^time-(n-1)xprev time by dealDate,shop from table
dealDate shop time mark
-----------------------
20190704 A    1000 0
20190704 A    1100 0
20190704 B    1130 0
20190704 B    1131 0
20190704 C    1132 0
20190704 A    1133 0
20190704 A    1134 1
20190704 B    1230 1
20190704 C    1232 0
20190704 C    1400 0
20190705 A    1000 0
20190705 A    1100 0
20190705 B    1130 0
20190705 B    1131 0
20190705 C    1132 0
20190705 A    1133 0
20190705 A    1134 1
20190705 B    1230 1
20190705 C    1232 0
20190705 C    1400 0

您可能希望将 dealDate 列采用日期格式,而不是 YYYYMMDD,因为 YYYYMMDD 会很长。例如,您可以使用"D"$string 20190705更改20190705,将其强制转换为数据 2019.07.05

最新更新