功能更新 - 具有动态列的多变量函数
Functional update - multivariable function with dynamic columns
如能提供以下帮助,我们将不胜感激!
我有两个 table:table1
是摘要 table 而 table2
是所有数据点的列表。我希望能够为 table1
.
中的每一行汇总 table2
中的信息
table1:flip `grp`constraint!(`a`b`c`d; 10 10 20 20);
table2:flip `grp`cat`constraint`val!(`a`a`a`a`a`b`b`b;`cl1`cl1`cl1`cl2`cl2`cl2`cl2`cl1; 10 10 10 10 10 10 20 10; 1 2 3 4 5 6 7 8);
function:{[grpL;constraintL;catL] first exec total: sum val from table2 where constraint=constraintL, grp=grpL,cat=catL};
update cl1:function'[grp;constraint;`cl1], cl2:function'[grp;constraint;`cl2] from table1;
这段代码的第四行实现了我想要的两个类别:cl1
和cl2
在 table1
中,我想用类别名称(cl1
、cl2
等)命名一个新列,并且我希望该列中的值是运行 该列上的函数的输出。
但是,我有数百个不同的类别,所以不想像第四行那样手动列出它们。我将如何传递类别列表,例如下面?
`cl1`cl2`cl3
您可以研究几种不同的方法。
最简单的方法是功能更新 - http://code.kx.com/wiki/JB:QforMortals2/queries_q_sql#Functional_update
不过,下面应该会更有用、更快捷、更整洁:
您的问题可以分为两部分。对于第一部分,您希望通过 grp 和约束在 table2 内创建每个类别的总和。至于第二部分,您希望将这些结果(查找)加入 table1.
中的相应记录
您可以使用 by
创建必要的组
q)exec val,cat by grp,constraint from table2
grp constraint| val cat
--------------| ------------------------------
a 10 | 1 2 3 4 5 `cl1`cl1`cl1`cl2`cl2
b 10 | 6 8 `cl2`cl1
b 20 | ,7 ,`cl2
不过请注意,这只会在您的 select 查询
中创建列的嵌套列表
接下来是 cat
组中的 sum each
q)exec sum each val group cat by grp,constraint from table2
grp constraint|
--------------| ------------
a 10 | `cl1`cl2!6 9
b 10 | `cl2`cl1!6 8
b 20 | (,`cl2)!,7
然后,要创建猫的列,您可以使用类似枢轴的语法 - http://code.kx.com/wiki/Pivot
q)cats:asc exec distinct cat from table2
q)exec cats#sum each val group cat by grp,constraint from table2
grp constraint| cl1 cl2
--------------| -------
a 10 | 6 9
b 10 | 8 6
b 20 | 7
现在您可以使用此查找 table 并为 table1
中的每一行编制索引
q)(exec cats#sum each val group cat by grp,constraint from table2)[table1]
cl1 cl2
-------
6 9
8 6
要用零填充空值,请使用克拉符号 - http://code.kx.com/wiki/Reference/Caret
q)0^(exec cats#sum each val group cat by grp,constraint from table2)[table1]
cl1 cl2
-------
6 9
8 6
0 0
0 0
现在您可以使用 join-each
加入从 table1 到结果的每一行
q)table1,'0^(exec cats#sum each val group cat by grp,constraint from table2)[table1]
grp constraint cl1 cl2
----------------------
a 10 6 9
b 10 8 6
c 20 0 0
d 20 0 0
HTH,肖恩
坚持你的方法,你只需要让你的更新语句起作用,然后像这样迭代列:
{![`table1;();0b;(1#x)!enlist ((';function);`grp;`constraint;1#x)]} each `cl1`cl2
假设您可以就地修改表 1。如果一定要保留原来的table1那么可以传值,虽然会消耗更多的内存
{![x;();0b;(1#y)!enlist ((';function);`grp;`constraint;1#y)]}/[table1;`cl1`cl2]
另一种方法是聚合、旋转和连接,尽管它不一定是更好的解决方案,因为您得到的是空值而不是零
a:select sum val by cat,grp,constraint from table2
p:exec (exec distinct cat from a)#cat!val by grp,constraint from a
table1 lj p
这种方法是传递类别列表的最简单方法
{table1^flip x!function'[table1`grp;table1`constraint;]each x}`cl1`cl2
如能提供以下帮助,我们将不胜感激!
我有两个 table:table1
是摘要 table 而 table2
是所有数据点的列表。我希望能够为 table1
.
table2
中的信息
table1:flip `grp`constraint!(`a`b`c`d; 10 10 20 20);
table2:flip `grp`cat`constraint`val!(`a`a`a`a`a`b`b`b;`cl1`cl1`cl1`cl2`cl2`cl2`cl2`cl1; 10 10 10 10 10 10 20 10; 1 2 3 4 5 6 7 8);
function:{[grpL;constraintL;catL] first exec total: sum val from table2 where constraint=constraintL, grp=grpL,cat=catL};
update cl1:function'[grp;constraint;`cl1], cl2:function'[grp;constraint;`cl2] from table1;
这段代码的第四行实现了我想要的两个类别:cl1
和cl2
在 table1
中,我想用类别名称(cl1
、cl2
等)命名一个新列,并且我希望该列中的值是运行 该列上的函数的输出。
但是,我有数百个不同的类别,所以不想像第四行那样手动列出它们。我将如何传递类别列表,例如下面?
`cl1`cl2`cl3
您可以研究几种不同的方法。 最简单的方法是功能更新 - http://code.kx.com/wiki/JB:QforMortals2/queries_q_sql#Functional_update
不过,下面应该会更有用、更快捷、更整洁:
您的问题可以分为两部分。对于第一部分,您希望通过 grp 和约束在 table2 内创建每个类别的总和。至于第二部分,您希望将这些结果(查找)加入 table1.
中的相应记录您可以使用 by
q)exec val,cat by grp,constraint from table2
grp constraint| val cat
--------------| ------------------------------
a 10 | 1 2 3 4 5 `cl1`cl1`cl1`cl2`cl2
b 10 | 6 8 `cl2`cl1
b 20 | ,7 ,`cl2
不过请注意,这只会在您的 select 查询
中创建列的嵌套列表接下来是 cat
组中的 sum each
q)exec sum each val group cat by grp,constraint from table2
grp constraint|
--------------| ------------
a 10 | `cl1`cl2!6 9
b 10 | `cl2`cl1!6 8
b 20 | (,`cl2)!,7
然后,要创建猫的列,您可以使用类似枢轴的语法 - http://code.kx.com/wiki/Pivot
q)cats:asc exec distinct cat from table2
q)exec cats#sum each val group cat by grp,constraint from table2
grp constraint| cl1 cl2
--------------| -------
a 10 | 6 9
b 10 | 8 6
b 20 | 7
现在您可以使用此查找 table 并为 table1
中的每一行编制索引q)(exec cats#sum each val group cat by grp,constraint from table2)[table1]
cl1 cl2
-------
6 9
8 6
要用零填充空值,请使用克拉符号 - http://code.kx.com/wiki/Reference/Caret
q)0^(exec cats#sum each val group cat by grp,constraint from table2)[table1]
cl1 cl2
-------
6 9
8 6
0 0
0 0
现在您可以使用 join-each
q)table1,'0^(exec cats#sum each val group cat by grp,constraint from table2)[table1]
grp constraint cl1 cl2
----------------------
a 10 6 9
b 10 8 6
c 20 0 0
d 20 0 0
HTH,肖恩
坚持你的方法,你只需要让你的更新语句起作用,然后像这样迭代列:
{![`table1;();0b;(1#x)!enlist ((';function);`grp;`constraint;1#x)]} each `cl1`cl2
假设您可以就地修改表 1。如果一定要保留原来的table1那么可以传值,虽然会消耗更多的内存
{![x;();0b;(1#y)!enlist ((';function);`grp;`constraint;1#y)]}/[table1;`cl1`cl2]
另一种方法是聚合、旋转和连接,尽管它不一定是更好的解决方案,因为您得到的是空值而不是零
a:select sum val by cat,grp,constraint from table2
p:exec (exec distinct cat from a)#cat!val by grp,constraint from a
table1 lj p
这种方法是传递类别列表的最简单方法
{table1^flip x!function'[table1`grp;table1`constraint;]each x}`cl1`cl2