q - 在 table 行上应用函数
q - apply function on table rowwise
给定一个 table 和一个函数
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
的原始版本时获得相同的结果感兴趣
谢谢!
您可以为此使用 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" 可能会获得更好的性能,例如
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 中,如果你能避免使用任何形式的 each 并坚持向量操作,你将获得更高的效率
给定一个 table 和一个函数
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
谢谢!
您可以为此使用 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" 可能会获得更好的性能,例如
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 中,如果你能避免使用任何形式的 each 并坚持向量操作,你将获得更高的效率