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
,如果其中有n
或更多事务t
,则将该行标记为真1
。否则标记为0
。
解释:
第 1 到 2 行,A在 内进行两次交易
t
。第 3 行到第 4 行,B在 内进行了两次交易
t
。第 5 行,C有它的第一笔交易。
第 6 行,A进行另一笔交易,但单元格未标记为 - 此交易与第一笔交易之间的间隔超过
t
(1000 -> 1133)。第 7 行,行被标记为A在(1100 -> 1133 -> 1134)内有
n
交易。t
第 8 行,行标记为B在(1130 -> 1131 -> 1230)内有
n
交易t
第 9 行和第 10 行,C进行了两次交易,但由于间隔超过
t
(1132 -> 1232 ---> 1400)而未标记
此外,这将每天刷新(DealDate
格式中包含一列YYYYMMDD
)
本质上,这模拟了每个商店的队列,其中每个推入堆栈的项目将根据队列中的项目数量进行标记,每个最后一个项目超过弹出间隔。
我怎样才能用 Q 在 KDB 中完成这个?日期和时间戳按降序排列。
解决方案
您可以使用:
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 ( 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
您可能希望交易日期列采用日期格式,而不是 YYYYMMDD,因为 YYYYMMDD 会很长。例如,您可以使用 20190705 将其转换为数据 2019.07.05 来更改"D"$string 20190705
推荐阅读
- javascript - 问题:javascript switch case 不适用于我的 var
- sharepoint - SharePoint 搜索不适用于隐藏库
- javascript - 没有 Node.Js 的 CkEditor simpleupload 适配器
- python - unique() 没有显示 Python 中的所有值
- java - java - 在具有列表返回类型的Java查询中调用参数值?
- azure - 如何使“Azure 服务总线”消息由实例池中的单个服务器实例处理?
- php - 获取替换前的字符串
- python - 使用 discord.py 的不和谐机器人代码根本不起作用
- php - 如何在 macOS big Sur 上使用 MAMP PHP
- python - 有什么办法可以避免 Turtle 减慢它必须打印的行数?