初始表
company time value
-------------------------
a 00:00:15.000 100
a 00:00:30.000 100
b 00:01:00.000 100
a 00:01:10.000 100
a 00:01:15.000 100
a 00:01:20.000 300
a 00:01:25.000 100
b 00:01:30.000 400
a 00:01:50.000 100
a 00:02:00.000 100
a 00:00:03.000 200
让t
= 1小时。
对于每一行,我想回顾t
时间。
属于t
的条目将形成一个时间窗口。我想得到max(time window) - min (time window) / number of events)
。
例如,如果现在是12:00
,并且总共有五个事件,12:00, 11:50, 11:40, 11:30, 10:30
,其中四个事件落在t
的窗口中,即12:00, 11:50, 11:40, 11:30
,结果将为12:00 - 11:30 / 4
。
此外,该窗口应只考虑具有相同值和公司名称的行。
结果表
company time value x
--------------------------------
a 00:00:15.000 100 0 (First event A).
a 00:00:30.000 100 15 (30 - 15 / 2 events).
b 00:01:00.000 100 0 (First event of company B).
a 00:01:10.000 100 55/3 = 18.33 (1:10 - 0:15 / 3 events).
a 00:01:15.000 100 60/4 = 15 (1:15 - 0:15 / 4 events).
a 00:01:20.000 300 0 (Different value).
a 00:01:25.000 100 55/4 = 13.75 (01:25 - 0:30 / 4 events).
b 00:01:30.000 400 0 (Different value and company).
a 00:01:50.000 100 40/4 = 10 (01:50 - 01:10 / 4 events).
a 00:02:00.000 100 50/5 = 10 (02:00 - 01:10 / 5 events).
a 00:03:00.000 200 0 (Different value).
任何帮助将不胜感激。如果有帮助,我问了一个类似的问题,该问题非常出色:Sum values from the previous N number of days in KDB?
表格查询
([] company:`a`a`b`a`a`a`a`b`a`a`a; time: 00:00:15.000 00:00:30.000 00:01:00.000 00:01:10.000 00:01:15.000 00:01:20.000 00:01:25.000 00:01:30.000 00:01:50.000 00:02:00.000 00:03:00.000; v: 100 100 100 100 100 300 100 400 100 100 200)
答案 0 :(得分:4)
您可能希望使用以下内容;
q)update x:((time-time[time binr time-01:00:00])%60000)%count each v where each time within/:flip(time-01:00:00;time) by company,v from t
company time v x
---------------------------------
a 00:15:00.000 100 0
a 00:30:00.000 100 7.5
b 01:00:00.000 100 0
a 01:10:00.000 100 18.33333
a 01:15:00.000 100 15
a 01:20:00.000 300 0
a 01:25:00.000 100 13.75
b 01:30:00.000 400 0
a 01:50:00.000 100 10
a 02:00:00.000 100 10
a 03:00:00.000 200 0
它使用time binr time-01:00:00
来获取每次前1小时的最短时间的索引。
然后(time-time[time binr time-01:00:00])%60000
以分钟为单位给出每个时间的各自时间范围(即时间-分钟时间)。
count each v where each time within/:flip(time-01:00:00;time)
给出此范围内的行数。
将两者相除并实现by company,v
只会将它们全部应用于具有相同company
和v
值的那些。
希望这会有所帮助。
凯文
答案 1 :(得分:1)
如果您的表按时间排序,则以下解决方案将为您提供所需的结果。如果尚未使用xasc
,您还可以按时间排序表格。
我还修改了表格,使时间具有不同的小时值。
q) t:([] company:`a`a`b`a`a`a`a`b`a`a`a; time: 00:15:00.000 00:30:00.000 01:00:00.000 01:10:00.000 01:15:00.000 01:20:00.000 01:25:00.000 01:30:00.000 01:50:00.000 02:00:00.000 03:00:00.000; v: 100 100 100 100 100 300 100 400 100 100 200)
q) f:{(`int$x-x i) % 60000*1+til[count x]-i:x binr x-01:00:00}
q) update res:f time by company,v from t
Output
company time v res
---------------------------------
a 00:15:00.000 100 0
a 00:30:00.000 100 7.5
b 01:00:00.000 100 0
a 01:10:00.000 100 18.33333
a 01:15:00.000 100 15
a 01:20:00.000 300 0
a 01:25:00.000 100 13.75
b 01:30:00.000 400 0
a 01:50:00.000 100 10
a 02:00:00.000 100 10
a 03:00:00.000 200 0
您可以修改函数f
来更改时间窗口值。或更改f
接受它作为输入参数。
说明:
我们将公司的时间向量,值传递给函数f
。它从每个时间值中减去1小时,然后使用binr
从输入时间向量中获取1小时窗口范围内第一次输入的索引。
q) i:x binr x-01:00:00
q) 0 0 0 0 1 2 2
之后,它将使用输出的索引来计算总计数。在这里,我将计数乘以60000,因为时差以毫秒为单位,因为它会将其强制转换为int
。
q) 60000*1+til[count x]-i
q) 60000 120000 180000 240000 240000 240000 300000
然后,我们最后减去每个值的最小和最大时间,然后将它们除以上述计数。由于时间向量是有序的(升序),因此可以将输入时间向量用作最大值和最小值,它们位于i
所指的索引处。
q) (`int$x-x i) % 60000*1+til[count x]-i