【问题标题】:KDB - Referencing functions from a tableKDB - 从表中引用函数
【发布时间】:2020-07-29 22:59:46
【问题描述】:

我是 kdb 的新手,我正在研究一个用例,以使用包含各种函数输入的表生成时间序列数据。表的每一行都包含由 id 和段作为键的函数输入,每行将调用一个函数。尽管使用暴力嵌套条件,但我已经弄清楚了如何识别哪个函数。

我的问题分为两部分

  1. 如何开始执行这些功能?
  2. 为每个 id 和段生成时间序列数据后,如何最好地将输出编译成一个单一的表(示例输出如下所述 - 我曾考虑为每个 id 一个表,然后分两步编译也可以,但我们会有数千个 ID)

下面是一个示例表和一些添加元数据的条件,包括应用哪个函数

        //Create sample table and add columns to identify unknown and desired function
        t:([id:`AAA`AAA`AAA`BBB`CCC;seg:1 2 3 1 1];aa: 1500 0n 400 40 900;bb:0n 200 30 40 0n;cc: .40 .25 0n 0n .35) 
        t: update Uknown:?[0N = aa;`aa;?[0N = bb;`bb;?[0N = cc;`cc;`UNK]]] from t
        t: update Call_Function:?[0N = aa;`Solveaa;?[0N = bb;`Solvebb;?[0N = cc;`Solvecc;`NoFunction]]] from t 

下面的示例函数使用表 t 中的输入来生成时间序列数据(例如这里限制为 5 个周期)并使用 X 进行测试

        //dummy function to generate output for first 5 time periods
        Solvebb:{[aa;cc]
             (aa%cc)*(1-exp(neg cc*1+til 5)) 
        }

        //test the function as an example for dummy output in result table below 
        x: flip enlist Solvebb[1500;.40]  //sample output for AAA seg1 from t for example

理想情况下,结果将是一个类似于下面的示例表

        t2: `id`seg xkey ("SIIIS";enlist",") 0:`:./Data/sampleOutput.csv 

        
id  seg| seg_idx tot_idx result  
-------| ------------------------
AAA 1  | 1       1       1,236.30
AAA 1  | 2       2       2,065.02
AAA 1  | 3       3       2,620.52
AAA 1  | 4       4       2,992.89
AAA 1  | 5       5       3,242.49
AAA 2  | 1       6
AAA 2  | 2       7
AAA 2  | 3       8
AAA 2  | 4       9
AAA 2  | 5       10
AAA 3  | 1       11
AAA 3  | 2       12
AAA 3  | 3       13
AAA 3  | 4       14
AAA 3  | 5       15
BBB 1  | 1       1
BBB 1  | 2       2
BBB 1  | 3       3
BBB 1  | 4       4
BBB 1  | 5       5
..

【问题讨论】:

    标签: kdb


    【解决方案1】:

    没有更多细节很难,但以下内容可能会有所帮助。

    首先,定义Solvebb 可能更容易,这样它就可以接受 3 个输入并简单地忽略中间的一个:

    q)Solvebb:{[aa;bb;cc](aa%cc)*(1-exp(neg cc*1+til 5))}
    

    并为表中的其他两个添加虚拟函数(注意,稍后使用 ungroup 很重要,这些函数的输出是列表):

    q)Solveaa:{[aa;bb;cc] (bb+cc;bb*cc)}
    q)Solvecc:{[aa;bb;cc] (aa+bb;aa*bb)}
    

    您可以将每个函数的每个调用应用于所有三个输入向量:

    q)update result:first[Call_Function]'[aa;bb;cc] by Call_Function from t
    id  seg| aa   bb  cc   Uknown Call_Function result
    -------| -------------------------------------------------------------------------------
    AAA 1  | 1500     0.4  bb     Solvebb       1236.3 2065.016 2620.522 2992.888 3242.493
    AAA 2  |      200 0.25 aa     Solveaa       200.25 50
    AAA 3  | 400  30       cc     Solvecc       430 12000f
    BBB 1  | 40   40       cc     Solvecc       80 1600f
    CCC 1  | 900      0.35 bb     Solvebb       759.3735 1294.495 1671.589 1937.322 2124.581
    

    您可以通过应用ungroup 函数来解开此表

    q)ungroup update result:first[Call_Function]'[aa;bb;cc] by Call_Function from t
    id  seg aa   bb  cc   Uknown Call_Function result
    ---------------------------------------------------
    AAA 1   1500     0.4  bb     Solvebb       1236.3
    AAA 1   1500     0.4  bb     Solvebb       2065.016
    AAA 1   1500     0.4  bb     Solvebb       2620.522
    AAA 1   1500     0.4  bb     Solvebb       2992.888
    AAA 1   1500     0.4  bb     Solvebb       3242.493
    AAA 2        200 0.25 aa     Solveaa       200.25
    AAA 2        200 0.25 aa     Solveaa       50
    AAA 3   400  30       cc     Solvecc       430
    AAA 3   400  30       cc     Solvecc       12000
    BBB 1   40   40       cc     Solvecc       80
    BBB 1   40   40       cc     Solvecc       1600
    CCC 1   900      0.35 bb     Solvebb       759.3735
    CCC 1   900      0.35 bb     Solvebb       1294.495
    CCC 1   900      0.35 bb     Solvebb       1671.589
    CCC 1   900      0.35 bb     Solvebb       1937.322
    CCC 1   900      0.35 bb     Solvebb       2124.581
    

    【讨论】:

    • 感谢 Jorge,这是有道理的,而且在您布置时非常简单。我需要使用额外的参数将它扩展到更大的函数,但这非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多