kdb+/q:将具有更新变量的迭代过程应用于列
kdb+/q: Apply iterative procedure with updated variable to a column
考虑以下过程 f:{[x] ..}
,起始值为 a:0
:
- 用
x
和 a
做点什么。输出保存为新版本a
,函数返回输出
- 对于下一个输入
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+x
和 a: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
考虑以下过程 f:{[x] ..}
,起始值为 a:0
:
- 用
x
和a
做点什么。输出保存为新版本a
,函数返回输出 - 对于下一个输入
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+x
和 a: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