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

Car*_*ein 1 kdb

给出下表:

初始表:

shop | time    
-----------
  A  | 1000
  A  | 1100
  B  | 1130
  B  | 1131
  C  | 1132
  A  | 1133
  A  | 1134
  B  | 1230
  C  | 1232
  C  | 1400
Run Code Online (Sandbox Code Playgroud)

结果表:

   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]
Run Code Online (Sandbox Code Playgroud)

哪里:

  • t = 1小时。

  • n = 3。

对于固定的时间间隔t,如果其中有n多个事务t,则将该行标记为true 1。否则标记为0

说明:

  • 第1到2行,A在中进行两次交易t

  • 第3至4行,B在中进行两次交易t

  • 第5行,C有其第一笔交易。

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

  • 第7行的行被标记为Ant(1100-> 1133-> 1134)内有事务。

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

  • 在第9行和第10行,C进行了两次交易,但是当间隔超过t(1132-> 1232 ---> 1400)时未作标记。

此外,每天都会刷新一次(DealDate格式中包含一列YYYYMMDD

本质上,这为每个商店模拟了一个队列,由此将根据队列中的项目数来标记推入堆栈的每个项目,每个最后一个项目超过弹出的间隔。

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

Cam*_*Kee 6

您可以使用:

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
Run Code Online (Sandbox Code Playgroud)

这将time-(n-1)xprev time为该商店(by shop)计算每个像元与在其后两行()发生的像元之间的时间差。

然后,由于我们不希望包含这些像元((t+1)^),所以它会使用大于t的值填充空值。

然后,它检查三个时间中最早的时间是否在当前时间的1小时之内,并在为true的位置分配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
Run Code Online (Sandbox Code Playgroud)

您可能希望将dealDate列的日期格式与YYYYMMDD相对,因为YYYYMMDD会很长。例如,您可以使用以下方式将20190705强制转换为数据2019.07.05"D"$string 20190705