kdb+/q:将具有更新变量的迭代过程应用于列

kdb+/q: Apply iterative procedure with updated variable to a column

考虑以下过程 f:{[x] ..},起始值为 a:0

  1. xa 做点什么。输出保存为新版本a,函数返回输出
  2. 对于下一个输入 x,重做该过程,但现在使用新的 a

对于单个值x,这个过程很容易构造。例如:

a:0;
f:{[x] a::a+x; :a}       / A simple example (actual function more complicated)

但是,如何使这样的函数在应用于 table 列时也能正常工作?

我不知道如何将 'intermediate saving of a variable' 的这个步骤合并到一个可以立即应用于列的函数中。这有什么特殊的技术吗?例如。当我在上面的示例中使用 table 列时,它会简单地计算 a+xa:0 所有行,而不是在每次迭代时更新 a

不需要为此使用全局变量 - 可以使用 scan - 参见 here.

例子--

生成 table -

q)t:0N!([] time:5?.z.p; sym:5?`3; price:5?100f; size:5?10000)
    time                          sym price    size
    -----------------------------------------------
    2002.04.04D18:06:07.889113280 cmj 29.07093 3994
    2007.05.21D04:26:13.021438816 llm 7.347808 496
    2010.10.30D10:15:14.157553088 obp 31.59526 1728
    2005.11.01D21:15:54.022395584 dhc 34.10485 5486
    2005.03.06D21:05:07.403334368 mho 86.17972 2318

带有简单累加器的示例 - 注意,如果需要,该函数可以访问其他参数(参见下一个示例):

q)update someCol:{[a;x;y;z] (a+1)}\[0;time;price;size] from t
    time                          sym price    size someCol
    -------------------------------------------------------
    2002.04.04D18:06:07.889113280 cmj 29.07093 3994 1
    2007.05.21D04:26:13.021438816 llm 7.347808 496  2
    2010.10.30D10:15:14.157553088 obp 31.59526 1728 3
    2005.11.01D21:15:54.022395584 dhc 34.10485 5486 4
    2005.03.06D21:05:07.403334368 mho 86.17972 2318 5

假设您想获得累积大小:

q)update cuSize:{[a;x;y;z] (a+z)}\[0;time;price;size] from t
    time                          sym price    size cuSize
    ------------------------------------------------------
    2002.04.04D18:06:07.889113280 cmj 29.07093 3994 3994
    2007.05.21D04:26:13.021438816 llm 7.347808 496  4490
    2010.10.30D10:15:14.157553088 obp 31.59526 1728 6218
    2005.11.01D21:15:54.022395584 dhc 34.10485 5486 11704
    2005.03.06D21:05:07.403334368 mho 86.17972 2318 14022

如果您想通过扫描传递多个 var,可以将更多值打包到第一个 var 中,方法是为其提供更复杂的结构:

q)update cuPriceAndSize:{[a;x;y;z] (a[0]+y;a[1]+z)}\[0 0;time;price;size] from t
    time                          sym price    size cuPriceAndSize
    --------------------------------------------------------------
    2002.04.04D18:06:07.889113280 cmj 29.07093 3994 29.07093 3994
    2007.05.21D04:26:13.021438816 llm 7.347808 496  36.41874 4490
    2010.10.30D10:15:14.157553088 obp 31.59526 1728 68.014   6218
    2005.11.01D21:15:54.022395584 dhc 34.10485 5486 102.1188 11704
    2005.03.06D21:05:07.403334368 mho 86.17972 2318 188.2986 14022

@MdSalih 的解决方案是正确的,我只是在这里解释你的情况下全局变量的可能原因和解决方案。

q) t:([]id: 1 2)
q)a:1

我想你可能一直这样使用它:

q) select k:{x:x+a;a::a+1;:x} id from t

输出:

k 
--
1
2

a值为2,表示函数只执行一次。原因是我们将完整的 id 列列表传递给函数,并且 (+) 是原子的,这意味着它会立即对完整列表进行操作。在下面的例子中。 2 将添加到列表中的所有项目。

q) 2 + (1;3;5)

正确的使用方法是'each':

q)select k:{x:x+a;a::a+1;:x} each id from t

输出:

k 
--
2
3