kdb+q中列的功能添加

kdb+q中列的功能添加,kdb,q-lang,Kdb,Q Lang,我有一个q表,其中非键列的数量是可变的。此外,这些列名的名称中包含一个整数。我想对这些列执行一些函数,而不实际使用它们的实际名称 我怎样才能做到这一点 例如: table: a | col10 col20 col30 1 | 2 3 4 2 | 5 7 8 // Assume that I have numbers 10, 20 ,30 obtained from column names I want som

我有一个q表,其中非键列的数量是可变的。此外,这些列名的名称中包含一个整数。我想对这些列执行一些函数,而不实际使用它们的实际名称

我怎样才能做到这一点

例如:

 table:   

 a |  col10  col20 col30 

 1 |    2      3     4
 2 |    5      7     8

 // Assume that I have numbers 10, 20 ,30 obtained from column names

    I want something like **update NewCol:10*col10+20*col20+30*col30 from table**

     except that no.of columns is not fixed so are their inlcluded numbers

我们想使用一个简单的函数更新示例,如下所示:

对于这个特定的查询,我们希望生成select子句的计算树,即函数update语句的最后一部分。最简单的方法是解析类似的语句,然后重新创建该格式:

q)/ create our table
q)t:([] c10:1 2 3; c20:10 20 30; c30:7 8 9; c40:0.1*4 5 6)
q)t
c10 c20 c30 c40
---------------
1   10  7   0.4
2   20  8   0.5
3   30  9   0.6

q)parse "update r:(10*c10)+(20*col20)+(30*col30) from t"
!
`t
()
0b
(,`r)!,(+;(*;10;`c10);(+;(*;20;`col20);(*;30;`col30)))
q)/ notice the last value, the parse tree
q)/ we want to recreate that using code
q){(*;x;`$"c",string x)} 10
*
10
`c10
q){(+;x;y)} over {(*;x;`$"c",string x)} each 10 20
+
(*;10;`c10)
(*;20;`c20)
q)makeTree:{{(+;x;y)} over {(*;x;`$"c",string x)} each x}

/ now write as functional update
q)![t;();0b; enlist[`res]!enlist makeTree 10 20 30]
c10 c20 c30 c40 res
-------------------
1   10  7   0.4 420
2   20  8   0.5 660
3   30  9   0.6 900

q)update r:(10*c10)+(20*c20)+(30*c30) from t
c10 c20 c30 c40 r
-------------------
1   10  7   0.4 420
2   20  8   0.5 660
3   30  9   0.6 900

我们想使用一个简单的函数更新示例,如下所示:

对于这个特定的查询,我们希望生成select子句的计算树,即函数update语句的最后一部分。最简单的方法是解析类似的语句,然后重新创建该格式:

q)/ create our table
q)t:([] c10:1 2 3; c20:10 20 30; c30:7 8 9; c40:0.1*4 5 6)
q)t
c10 c20 c30 c40
---------------
1   10  7   0.4
2   20  8   0.5
3   30  9   0.6

q)parse "update r:(10*c10)+(20*col20)+(30*col30) from t"
!
`t
()
0b
(,`r)!,(+;(*;10;`c10);(+;(*;20;`col20);(*;30;`col30)))
q)/ notice the last value, the parse tree
q)/ we want to recreate that using code
q){(*;x;`$"c",string x)} 10
*
10
`c10
q){(+;x;y)} over {(*;x;`$"c",string x)} each 10 20
+
(*;10;`c10)
(*;20;`c20)
q)makeTree:{{(+;x;y)} over {(*;x;`$"c",string x)} each x}

/ now write as functional update
q)![t;();0b; enlist[`res]!enlist makeTree 10 20 30]
c10 c20 c30 c40 res
-------------------
1   10  7   0.4 420
2   20  8   0.5 660
3   30  9   0.6 900

q)update r:(10*c10)+(20*c20)+(30*c30) from t
c10 c20 c30 c40 r
-------------------
1   10  7   0.4 420
2   20  8   0.5 660
3   30  9   0.6 900

如@Ryan Hamilton所示,您可以创建一个函数式表单查询,总的来说,这将是最好的方法,因为它非常灵活。但是如果你只是想把这些加起来,乘以一些权重,我很喜欢通过其他途径

编辑:遗漏了您所说的列名称中的数字可能会有所不同,在这种情况下,您可以轻松调整此值。如果列名前面都有相同数量的字母,只需删除这些字母,然后将剩余的字母解析为int或其他字母即可。否则,如果数字嵌入到文本中,请签出


我还没有在一个大的表上测试过这一点,因此请注意,emptor可以创建一个函数式表单查询,正如@Ryan Hamilton所指出的,总体而言,这将是最好的方法,因为它非常灵活。但是如果你只是想把这些加起来,乘以一些权重,我很喜欢通过其他途径

编辑:遗漏了您所说的列名称中的数字可能会有所不同,在这种情况下,您可以轻松调整此值。如果列名前面都有相同数量的字母,只需删除这些字母,然后将剩余的字母解析为int或其他字母即可。否则,如果数字嵌入到文本中,请签出


我还没有在一个大的表上测试过这一点,所以请注意,如果表是非常通用的,那么@Ryan建议的functional select就是一种方法,即列名可能会有所不同,列数未知

然而,我更喜欢@JPC使用vector解决乘法和求和问题的方式,即更新res:sum 10 20 30*col10;col20;表中的col30

让我们将这两种方法与一些极端情况结合起来:

q)show t:1!flip(`a,`$((10?2 3 4)?\:.Q.a),'string 10?10)!enlist[til 100],0N 100#1000?10
a | vltg4 pnwz8 mifz5 pesq7 fkcx4 bnkh7 qvdl5 tl5 lr2 lrtd8
--| -------------------------------------------------------
0 | 3     3     0     7     9     5     4     0   0   0
1 | 8     4     0     4     1     6     0     6   1   7
2 | 4     7     3     0     1     0     3     3   6   4
3 | 2     4     2     3     8     2     7     3   1   7
4 | 3     9     1     8     2     1     0     2   0   2
5 | 6     1     4     5     3     0     2     6   4   2
..
q)show n:"I"$string[cols get t]inter\:.Q.n
4 8 5 7 4 7 5 5 2 8i
q)show c:cols get t
`vltg4`pnwz8`mifz5`pesq7`fkcx4`bnkh7`qvdl5`tl5`lr2`lrtd8
q)![t;();0b;enlist[`res]!enlist({sum x*y};n;enlist,c)]
a | vltg4 pnwz8 mifz5 pesq7 fkcx4 bnkh7 qvdl5 tl5 lr2 lrtd8 res
--| -----------------------------------------------------------
0 | 3     3     0     7     9     5     4     0   0   0     176
1 | 8     4     0     4     1     6     0     6   1   7     226
2 | 4     7     3     0     1     0     3     3   6   4     165
3 | 2     4     2     3     8     2     7     3   1   7     225
4 | 3     9     1     8     2     1     0     2   0   2     186
5 | 6     1     4     5     3     0     2     6   4   2     163
..

我认为@Ryan建议的functional select是一种方法,如果表非常通用,即列名可能不同,列数未知

然而,我更喜欢@JPC使用vector解决乘法和求和问题的方式,即更新res:sum 10 20 30*col10;col20;表中的col30

让我们将这两种方法与一些极端情况结合起来:

q)show t:1!flip(`a,`$((10?2 3 4)?\:.Q.a),'string 10?10)!enlist[til 100],0N 100#1000?10
a | vltg4 pnwz8 mifz5 pesq7 fkcx4 bnkh7 qvdl5 tl5 lr2 lrtd8
--| -------------------------------------------------------
0 | 3     3     0     7     9     5     4     0   0   0
1 | 8     4     0     4     1     6     0     6   1   7
2 | 4     7     3     0     1     0     3     3   6   4
3 | 2     4     2     3     8     2     7     3   1   7
4 | 3     9     1     8     2     1     0     2   0   2
5 | 6     1     4     5     3     0     2     6   4   2
..
q)show n:"I"$string[cols get t]inter\:.Q.n
4 8 5 7 4 7 5 5 2 8i
q)show c:cols get t
`vltg4`pnwz8`mifz5`pesq7`fkcx4`bnkh7`qvdl5`tl5`lr2`lrtd8
q)![t;();0b;enlist[`res]!enlist({sum x*y};n;enlist,c)]
a | vltg4 pnwz8 mifz5 pesq7 fkcx4 bnkh7 qvdl5 tl5 lr2 lrtd8 res
--| -----------------------------------------------------------
0 | 3     3     0     7     9     5     4     0   0   0     176
1 | 8     4     0     4     1     6     0     6   1   7     226
2 | 4     7     3     0     1     0     3     3   6   4     165
3 | 2     4     2     3     8     2     7     3   1   7     225
4 | 3     9     1     8     2     1     0     2   0   2     186
5 | 6     1     4     5     3     0     2     6   4   2     163
..

这是另一个更快的解决方案

t,'([]res:(+/)("I"$(string tcols) inter\: .Q.n) *' (value t) tcols:(cols t) except  keys t)
通过花费一些时间,我们也可以减少字数。逻辑是这样的:

a:"I"$(string tcols) inter\: .Q.n
这里我首先从列名中提取整数,并将它们存储在向量中。变量“tcols”在查询的末尾声明,该查询只不过是表的列,键列除外

b:(value t) tcols:(cols t) except keys t
这里我提取每个列向量

c:(+/) a *' b
将每列向量b乘以其整数向量a,再加上相应的 每个结果列表中的值

t,'([]res:c)

最后,将结果存储在临时表中并将其连接到t。

这里是另一个更快的解决方案

t,'([]res:(+/)("I"$(string tcols) inter\: .Q.n) *' (value t) tcols:(cols t) except  keys t)
通过花费一些时间,我们也可以减少字数。逻辑是这样的:

a:"I"$(string tcols) inter\: .Q.n
这里我首先从列名中提取整数,并将它们存储在向量中。变量“tcols”在查询的末尾声明,该查询只不过是表的列,键列除外

b:(value t) tcols:(cols t) except keys t
这里我提取每个列向量

c:(+/) a *' b
将每列向量b乘以其整数向量a,再加上相应的 每个结果列表中的值

t,'([]res:c)

最后将结果存储在临时表中,并将其连接到t。

嗨,我尝试在这个表上使用相同的技巧。但它仍然显示出错误。t:[]a1:13;a2:2.4;col:a1a2;康斯特:12![t;;0b;登记['New]!登记+,{*;x;y}'[const;col]]。你能帮我吗?嗨,我试过在这张桌子上用同样的把戏。但它仍然显示出错误。t:[]a1:13;a2:2.4;col:a1a2;康斯特:12![t;;0b;登记['New]!登记+,{*;x;y}'[const;col]]。你能帮我解决这个问题吗?有趣的是,我实际上认为这个解决方案在我的机器上速度较慢。我认为,通过创建和添加col-wise的诱惑,而不是直接更新为一个新的专栏,会出现一些轻微的放缓。一些简短的提示:*已经是原子的了,所以不需要“.+/实际上是总和,两者似乎都在我的机器上运行。我认为值翻转值键控_表比值键控_表cols[键控_表]快,键除外
keyed_table,这在您的机器上不同吗?有趣的是,我实际上认为这个解决方案在我的机器上速度较慢。我认为,通过创建和添加col-wise的诱惑,而不是直接更新为一个新的专栏,会出现一些轻微的放缓。一些简短的提示:*已经是原子的了,所以不需要“.+/实际上是总和,两者似乎都在我的机器上运行。我认为值翻转值键控表比值键控表cols[键控表]快,但键控表除外,这在您的机器上不同吗?