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

时间:2019-07-05 03:20:59

标签: 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,如果n内有t个或更多事务,则将该行标记为true 1。否则标记为0

说明:

  • 第1行到第2行, A t内进行两次交易。

  • 第3行到第4行, B t内进行两次交易。

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

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

  • 第7行,行被标记为 A n(1100-> 1133-> 1134)内有t个交易。

  • 第8行,行标记为 B ,在n内有t个交易记录(1130-> 1131-> 1230)

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

    < / li>

此外,它每天都会刷新(DealDate列包含在YYYYMMDD格式中)

从本质上讲,这为每个商店模拟了一个队列,通过该队列,将根据队列中的项目数来标记推送到堆栈中的每个项目,而每个最后一个项目都超过该间隔。

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

1 个答案:

答案 0 :(得分:6)

您可以使用:

@sink(type='inMemory', topic='{{symbol}}', 
     @map(type='json', 
         @payload( """{"StockData":{"Symbol":"{{symbol}}","Price":{{price}}}""")))
define stream BarStream (symbol string, price float, volume long);

这将为该商店(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的值填充空值。

然后,它检查三个时间中最早的时间是否在当前时间的1小时之内,并在为true的地方分配1((t+1)^)。

还可以通过添加t>=来刷新每个日期:

by dealDate

您可能希望将DealDate列的日期格式与YYYYMMDD相对,因为YYYYMMDD会很长。例如,您可以通过使用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

将其强制转换为数据2019.07.05来更改20190705
相关问题