了解如何阅读 kdb 中的每右和每左组合
Understanding how to read each-right and each-left combined in kdb
来自 q for mortals,我正在努力理解如何阅读此内容,并从逻辑上理解它。
1 2 3,/:\:10 20
我知道结果是完整形式的叉积:raze 1 2 3,/:\:10 20
。
但是从左到右阅读,我目前无法理解这会产生什么(在我的脑海中)
\:10 20
结合1 2 3,/:
??
帮助理解如何清楚地阅读本文(用文字或清晰的逻辑)将不胜感激。
当我在 q 中编写语法时,我发现自己在脑海中说了以下内容。 q 从右到左工作。
Internal Monologue -> Join the string on the right onto each of the strings on the left
code -> "ABC",\:"-D"
result -> "A-D"
"B-D"
"C-D"
我认为这是理解它的一种简单方法。 'join' 可以替换成任何...
Internal Monologue -> Does the string on the right match any of the strings on the left
code -> ("Cat";"Dog";"CAT";"dog")~\:"CAT"
result -> 0010b
每个权利都是相同的概念,将它们组合起来也很简单;
Internal Monologue -> Does each of the strings on the right match each of the strings on the left
code -> ("Cat";"Dog";"CAT";"dog")~\:/:("CAT";"Dog")
result -> 0010b
0100b
因此在您的示例中 1 2 3,/:\:10 20
- 您说的是 'Join each of the elements on the right to each of the elements on the left'
希望对您有所帮助!!
编辑 添加一个现实世界的例子.... - 考虑以下 table
q)show tab:([] upper syms:10?`2; names:10?("Robert";"John";"Peter";"Jenny"); amount:10?til 10)
syms names amount
--------------------
CF "Peter" 8
BP "Robert" 1
IC "John" 9
IN "John" 5
NM "Peter" 4
OJ "Jenny" 6
BJ "Robert" 6
KH "John" 1
HJ "Peter" 8
LH "John" 5
q)
我想得到名字是罗伯特的所有记录,你可以做; select from tab where names like "Robert"
但是,如果您想获得名称为 Robert 或 John 的结果,那么使用我们的 each-left 和 each-right 是一个完美的方案。
考虑名称列 - 它是一个字符串列表(每个元素都是字符列表的列表)。我们要问的是 'does any of the strings in the names column match any of the strings we want to find'... 翻译成 (namesList)~\:/:(list;of;names;to;find)
。这是步骤;
q)(tab`names)~\:/:("Robert";"John")
0100001000b
0011000101b
根据该结果,我们需要一个已编译的布尔值列表,其中每个元素对 Robert OR John 都为真 - 例如,如果您查看两个列表的索引 1,Robert 为 1b,John 为 0b - 在我们的结果中,索引 1 处的值应为 1b。索引 2 应该是 1b,索引 3 应该是 1b,索引 4 应该是 0b 等等...为此,我们可以应用 any
函数(或 max 或 sum!)。结果就是;
q)any(tab`names)~\:/:("Robert";"John")
0111001101b
把它们放在一起,我们得到;
q)select from tab where any names~\:/:("Robert";"John")
syms names amount
--------------------
BP "Robert" 1
IC "John" 9
IN "John" 5
BJ "Robert" 6
KH "John" 1
LH "John" 5
q)
首先,q 从右到左执行(因此通常是读取)。这意味着它将 \:
解释为应用于前一个函数的修饰符,它本身是由 /:
副词修饰的简单连接。所以读这个的方法是 "Apply join each-right to each of the left-hand arguments."
在这种情况下,您将两个副词应用于连接 - \:10 20
本身在这里没有实际意义。
我发现还可以查看代码生成 2x6 矩阵的相反情况 1 2 3,\:/:10 20
、运行,我将其描述得更像 "apply join each-left to each of the right hand arguments" ... 我希望这是有道理的。
另一种可能有帮助的语法是 ,/:\:[1 2 3;10 20]
- 这可能很有用,因为它非常清楚您正在应用的函数是什么,并且等同于您的就地表示法。
来自 q for mortals,我正在努力理解如何阅读此内容,并从逻辑上理解它。
1 2 3,/:\:10 20
我知道结果是完整形式的叉积:raze 1 2 3,/:\:10 20
。
但是从左到右阅读,我目前无法理解这会产生什么(在我的脑海中)
\:10 20
结合1 2 3,/:
??
帮助理解如何清楚地阅读本文(用文字或清晰的逻辑)将不胜感激。
当我在 q 中编写语法时,我发现自己在脑海中说了以下内容。 q 从右到左工作。
Internal Monologue -> Join the string on the right onto each of the strings on the left
code -> "ABC",\:"-D"
result -> "A-D"
"B-D"
"C-D"
我认为这是理解它的一种简单方法。 'join' 可以替换成任何...
Internal Monologue -> Does the string on the right match any of the strings on the left
code -> ("Cat";"Dog";"CAT";"dog")~\:"CAT"
result -> 0010b
每个权利都是相同的概念,将它们组合起来也很简单;
Internal Monologue -> Does each of the strings on the right match each of the strings on the left
code -> ("Cat";"Dog";"CAT";"dog")~\:/:("CAT";"Dog")
result -> 0010b
0100b
因此在您的示例中 1 2 3,/:\:10 20
- 您说的是 'Join each of the elements on the right to each of the elements on the left'
希望对您有所帮助!!
编辑 添加一个现实世界的例子.... - 考虑以下 table
q)show tab:([] upper syms:10?`2; names:10?("Robert";"John";"Peter";"Jenny"); amount:10?til 10)
syms names amount
--------------------
CF "Peter" 8
BP "Robert" 1
IC "John" 9
IN "John" 5
NM "Peter" 4
OJ "Jenny" 6
BJ "Robert" 6
KH "John" 1
HJ "Peter" 8
LH "John" 5
q)
我想得到名字是罗伯特的所有记录,你可以做; select from tab where names like "Robert"
但是,如果您想获得名称为 Robert 或 John 的结果,那么使用我们的 each-left 和 each-right 是一个完美的方案。
考虑名称列 - 它是一个字符串列表(每个元素都是字符列表的列表)。我们要问的是 'does any of the strings in the names column match any of the strings we want to find'... 翻译成 (namesList)~\:/:(list;of;names;to;find)
。这是步骤;
q)(tab`names)~\:/:("Robert";"John")
0100001000b
0011000101b
根据该结果,我们需要一个已编译的布尔值列表,其中每个元素对 Robert OR John 都为真 - 例如,如果您查看两个列表的索引 1,Robert 为 1b,John 为 0b - 在我们的结果中,索引 1 处的值应为 1b。索引 2 应该是 1b,索引 3 应该是 1b,索引 4 应该是 0b 等等...为此,我们可以应用 any
函数(或 max 或 sum!)。结果就是;
q)any(tab`names)~\:/:("Robert";"John")
0111001101b
把它们放在一起,我们得到;
q)select from tab where any names~\:/:("Robert";"John")
syms names amount
--------------------
BP "Robert" 1
IC "John" 9
IN "John" 5
BJ "Robert" 6
KH "John" 1
LH "John" 5
q)
首先,q 从右到左执行(因此通常是读取)。这意味着它将 \:
解释为应用于前一个函数的修饰符,它本身是由 /:
副词修饰的简单连接。所以读这个的方法是 "Apply join each-right to each of the left-hand arguments."
在这种情况下,您将两个副词应用于连接 - \:10 20
本身在这里没有实际意义。
我发现还可以查看代码生成 2x6 矩阵的相反情况 1 2 3,\:/:10 20
、运行,我将其描述得更像 "apply join each-left to each of the right hand arguments" ... 我希望这是有道理的。
另一种可能有帮助的语法是 ,/:\:[1 2 3;10 20]
- 这可能很有用,因为它非常清楚您正在应用的函数是什么,并且等同于您的就地表示法。