在某些条件下将数据分组到kdb中

时间:2018-03-01 10:15:38

标签: kdb

我有一个名为raw的主数据框,如下所示:

tab:([]date:2018.02.05 2018.02.05 2018.02.06 2018.02.06;time:01:30:25.000 02:30:45.000 04:15:15.000 02:15:15.000;vol:50 55 64 12; name:`A`B`B`A)

date           time         vol     name   
2018.02.05     1:30:25      50       A
2018.02.05     2:30:45      55       B
2018.02.06     4:15:15      64       B
2018.02.06     2:15:15      12       A

我需要根据以下条件创建一个新表:

在两个特定日期之间,我需要找到两小时内名字B的累积量为100的时间。

我认为应该运作的逻辑:按时间的升序排列数据。在(time [i]:time [i] + 2hrs)内添加所有vol by name =`B的时间。如果暨卷> 100,返回时间间隔和相应的日期。继续i +1。我是kdb的新手,所以我在实施它时遇到了困难。

示例输出:

time1          time2         date1         date2
1:30:00        3:30:00       2018.02.05    2018.02.05
23:00:00       1:00:00       2018.02.05    2018.02.06

对此的任何线索表示赞赏。谢谢

2 个答案:

答案 0 :(得分:1)

我相信使用aj

可以解决您的问题

最初,正如您所指出的,该表应按时间排序

(

然后,应使用总和

创建卷的累积总和
) VALUES(?)';
connection.query(sql, ${names[i]}, function(err,  result){ ... })

然后使用aj - 获取每次不在2小时内的卷的累积总和。

`time xasc `tab;

然后我们可以做cumvol - cumvol2来获得每2小时的总体积

tab:update cumvol:sums vol by name from tab

然后一个简单的select语句可以得到cumvol大于100的时间

aj[`name`time;tab;select time:time+02:00,name,cumvol2:cumvol from tab]

可以添加到此的改进是在aj中的第二个表上添加分组属性。 对此的另一个改进是将日期和时间格式化为单个时间戳或日期时间。

有关函数aj和sums的更多信息可以在这里找到:

https://chromedriver.storage.googleapis.com/index.html?path=2.35/

http://code.kx.com/q/ref/joins/#aj-aj0-asof-join

答案 1 :(得分:1)

您也可以使用window join wj1。给出示例表:

t:`time xasc ([]time:(1000?2018.02.05 2018.02.06)+1000?24:00:00;sym:1000?`A`B`C;vol:1000?10);

以下函数在相对于时间戳的2小时窗口中聚合vol,并传递表t,开始日期s,结束日期e和名称{{ 1}}。

n

运行名称/ sym fw:{[t;s;e;n] r:@[;`sym;`p#]`sym`time xasc select from t where time.date within(s;e),sym=n; :select from wj1[r[`time]-/:02:00 00:00;`time;r;(r;(sum;`vol))] where vol>100; }; 会给出:

B

它也可以修改为所有名称/ syms的所有结果:

q)fw[t;2018.02.05;2018.02.06;`B]
time                          sym vol
-------------------------------------
2018.02.05D18:12:39.000000000 B   104
2018.02.05D18:35:47.000000000 B   101
2018.02.05D18:40:17.000000000 B   102
...

这次没有名字/ sym运行:

fw1:{[t;s;e]
  r:@[;`sym;`p#]`sym`time xasc select from t where time.date within(s;e);
  :select from wj1[r[`time]-/:02:00 00:00;`sym`time;r;(r;(sum;`vol))] where vol>100;
 };

虽然这种方法效率低于使用q)fw1[t;2018.02.05;2018.02.06] time sym vol ------------------------------------- 2018.02.05D02:01:36.000000000 A 106 2018.02.05D02:52:23.000000000 A 103 2018.02.05D03:06:51.000000000 A 105 ... ,但它仍然说明了如何通过窗口连接实现此目的。