给出一个表和一个函数
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
因为内部函数symf
和datef
无法分别应用于整个列c2
,c3
。
如果我不想要更改函数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
谢谢!
答案 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中,如果您可以避免使用任何形式的每种形式并坚持矢量操作,那么您将获得更高的效率