【问题标题】:Alternative to using ungroup in kdb?在 kdb 中使用 ungroup 的替代方法?
【发布时间】:2020-04-07 15:05:07
【问题描述】:

我在 KDB 中有两个表。

一个是带有日期时间、符号列的时间序列(跨越多个日期,例如可以是 1 毫米行或 2 毫米行)。每个时间点都有相同数量的符号和很少的其他标准列,例如价格。 我们称之为 t1:

`date`datetime`sym`price

另一个表是这样的结构:

`date`sym`factors`weights 

其中 factor 是一个列表, weights 是每个 sym 的等长列表。 我们称之为 t2。

我正在对这两个表进行左连接,然后取消组合。 每个符号的因子和权重的长度不相等。

我正在做以下事情:

select sum (weights*price) by date, factors from ungroup t1 lj `date`sym xkey t2 

但是,这非常慢,如果 t1 有一百万行或更多行,可能会慢到 5-6 秒。

致电所有 kdb 专家寻求建议!

编辑:

这是一个完整的例子: (对于定义 t1 和 t2 的迂回方式表示歉意)

interval: `long$`time$00:01:00; 
hops: til 1+ `int$((`long$(et:`time$17:00)-st:`time$07:00))%interval;
times: st + `long$interval*hops; 
dates: .z.D - til .z.D-.z.D-10; 
timepoints: ([] date: dates) cross ([] time:times); 
syms: ([] sym: 300?`5); 
universe: timepoints cross syms; 
t1: update datetime: date+time, price:count[universe]?100.0 from universe;
t2: ([] date:dates) cross syms; 
/ note here my real life t2, doesn't have a count of 10 weights/factors for each sym, it can vary by sym. 
t2: `date`sym xkey update factors: count[t2]#enlist 10?`5, weights: count[t2]#enlist 10?10 from t2; 

/ what is slow is the ungroup 
select sum weights*price by date, datetime, factors from ungroup t1 lj t2

【问题讨论】:

  • 嗨,你能举个例子吗?
  • 是的,现在提供一个

标签: performance kdb


【解决方案1】:

避免取消组合的一种方法是使用矩阵(又名列表列表)并利用优化的矩阵乘法$ 在这里看到:https://code.kx.com/q/ref/mmu/

在我下面的方法中,我不是将 t2 加入到 t1 以取消分组,而是将 t1 分组并加入到 t2(从而将所有内容保留为列表列表),然后使用一些矩阵操作(最后一个取消组合在最后较小的集合)

q)\ts res:select sum weights*price by date, factors from ungroup t1 lj t2
4100 3035628112
q)\ts resT:ungroup exec first factors,sum each flip["f"$weights]$price by date:date from t2 lj select price by date,sym from t1;
76 83892800

q)(0!res)~`date`factors xasc `date`factors`weights xcol resT
1b

你可以看到它更快(至少在我的机器上),结果是相同的,除了排序和列名。

您可能仍需要稍微修改此解决方案以在您的实际用例中工作(使用可变权重等 - 在这种情况下,如果必要,可能会在每个符号上强制使用统一数量的权重填充零)

【讨论】:

  • 如果这需要在每个时间点完成怎么办?而不是每个日期。我犯了一个错误。结果应该是:select sum weights*price by date, datetime, factor from ungroup t1 lj t2,这意味着我不能将t2加入t1。强制执行统一数量的权重/因子是可行的,所以这绝对不是问题。
  • 在这种情况下,原来的左连接顺序更好:ungroup exec first factors,sum each flip["f"$weights]$price by datetime:datetime from t1 lj t2
  • 如果日期总是与日期时间的日期部分匹配,那么按日期按日期时间聚合是多余的,所以我把它排除在外
  • 不确定这是否给了我正确的答案?很多日期点丢失等
  • 这与您在上面给出的第二个查询并使用您的示例表相同。 (delete date from 0!select sum weights*price by date, datetime, factors from ungroup t1 lj t2)~`datetime`factors xasc `datetime`factors`weights xcol ungroup exec first factors,sum each flip["f"$weights]$price by datetime:datetime from t1 lj t2
猜你喜欢
  • 1970-01-01
  • 2018-01-04
  • 2018-05-21
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-14
  • 2015-05-22
相关资源
最近更新 更多