q - 在表格上按行应用函数

时间:2018-01-19 09:49:36

标签: kdb q-lang

给出一个表和一个函数

t:([] c1:1 2 3; c2:`a`b`c; c3:13:00 13:01 13:02)
f:{[int;sym;date] 
    symf:{$[x=`a;1;x=`b;2;3]};
    datef:{$[x=13:00;1;x=13:01;2;3]};
    r:int + symf[sym] + datef[date];
    r
 };

我注意到,当将函数f应用到t的列上时,整个列都会传递到f,如果它们可以原子操作,那么输出将是与输入长度相同,生成新列。但是在我们的例子中,这不起作用:

update newcol:f[c1;c2;c3] from t / 'type error

因为内部函数symfdatef无法分别应用于整个列c2c3

如果我想要更改函数f,我该如何逐行应用它并将值收集到t中的新列中。

执行此操作的q样式最多的方法是什么?

修改

如果不改变f真的很不方便,可以解决这个问题

f:{[arglist]
    int:arglist 0;
    sym:arglist 1;
    date:arglist 2; 
    symf:{$[x=`a;1;x=`b;2;3]};
    datef:{$[x=13:00;1;x=13:01;2;3]};
    r:int + symf[sym] + datef[date];
    r
 };

f each (t`c1),'(t`c2),'(t`c3)

在使用f

的原始版本时,我仍然有兴趣获得相同的结果

谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用each-both,例如

q)update newcol:f'[c1;c2;c3] from t
c1 c2 c3    newcol
------------------
1  a  13:00 3
2  b  13:01 6
3  c  13:02 9

然而,通过将f修改为" vectorised"您可能会获得更好的性能。 e.g。

q)f2
{[int;sym;date]
    symf:3^(`a`b!1 2)sym;
    datef:3^(13:00 13:01!1 2)date;
    r:int + symf + datef;
    r
 }
q)update newcol:f2[c1;c2;c3] from t
c1 c2 c3    newcol
------------------
1  a  13:00 3
2  b  13:01 6
3  c  13:02 9
q)\ts:1000 update newcol:f2[c1;c2;c3] from t
4 1664
q)\ts:1000 update newcol:f'[c1;c2;c3] from t
8 1680

一般来说,在KDB中,如果您可以避免使用任何形式的每种形式并坚持矢量操作,那么您将获得更高的效率