【问题标题】:KDB/Q: How to write a loop and append output table?KDB/Q:如何编写循环和追加输出表?
【发布时间】:2020-09-02 05:38:12
【问题描述】:

免责声明:我对 Q 语言很陌生,所以请原谅我的愚蠢问题。 我有一个函数,目前采用 2 个参数(日期;符号)。它运行良好 1 符号和 1 天。但是,我需要在多个符号和日期上执行此操作,这将需要很长时间。 如何创建一个在每个 sym 和每个日期运行该函数的循环? 在python中,它是直截了当的:

for date in datelist:
    for sym in symlist:
        func(date,sym)

我怎样才能在 Q 中做类似的事情?以及如何动态更改输出表名称并将它们附加到 1 个表中?

目前,我正在使用以下内容:

output: raze .[function] peach paralist

其中 paralist 是参数对列表:((2020.06.01;ABC);(2020.06.01;XYZ)) 但恕我直言,这远非有效。 在 Q 中实现这一目标的最佳方法是什么?

【问题讨论】:

  • 你的用例是什么?您是否需要在其他地方使用所有日期符号文件?你用的是hdb吗?我得到的印象就是你想要创造的

标签: kdb


【解决方案1】:

如果你有一个给定的函数foo,我会概括一切,它将对一个原子dt 和一个向量s 进行操作

q)foo:{[dt;s] dt +\: s}
q)dt:10?10
q)s:100?10
q)dt
8 1 9 5 4 6 6 1 8 5
q)s
4 9 2 7 0 1 9 2 1 8 8 1 7 2 4 5 4 2 7 8 5 6 4 1 3 3 7 8 2 1 4 2 8 0 5 8 5 2 8..
q)foo[;s] each dt
12 17 10 15 8 9  17 10 9  16 16 9  15 10 12 13 12 10 15 16 13 14 12 9  11 11 ..
5  10 3  8  1 2  10 3  2  9  9  2  8  3  5  6  5  3  8  9  6  7  5  2  4  4  ..
13 18 11 16 9 10 18 11 10 17 17 10 16 11 13 14 13 11 16 17 14 15 13 10 12 12 ..
9  14 7  12 5 6  14 7  6  13 13 6  12 7  9  10 9  7  12 13 10 11 9  6  8  8  ..

解决方案是将symList 投影到相关函数上,然后将each(或peach)用于date 变量。

如果您的函数需要原子datesym,那么您可以创建一个新函数来实现它

q)bar:{[x;y] foo[x;] each y};

【讨论】:

    【解决方案2】:
    datelist:`date$10?10
    symlist:10?`IBM`MSFT`GOOG
    function:{0N!(x;y)}
    
    {.[function;x]} peach datelist cross symlist
    

    cross 将返回 sym 和 date 的所有组合 这是你需要的吗?

    【讨论】:

    • 对不起,我想这就是我已经在做的事情了。我需要的是在 1 个 date-sym 上运行该函数,并输出到一个表中,然后再为另一个 date-sym 执行此操作,依此类推。应根据日期和符号更改输出表的名称。例如输出20191005ABC、输出20191006ABC等
    【解决方案3】:

    尝试使用两个“双”'

    raze function'[datelist]'[symlist]
    

    peacheach 在这里不起作用。它们不是运算符,而是带有两个参数的匿名函数:eachk){x'y}。这就是为什么function each list1 each list2 语句无效,但function'[list1]'[list2] 有效。

    【讨论】:

      【解决方案4】:

      通过阅读您对另一个答案的回复,您希望使用唯一名称保存结果是吗?看看这个解决方案,使用 set to save and get to retrieve。

      q)t:flip enlist each `colA`colB!(100;`name)
      q)t
      colA colB
      ---------
      100  name
      q)f:{[date;sym]tblName:`$string[date],string sym;tblName set update date:date,sym:sym from t}
      q)newTbls:f'[.z.d+til 3;`AAA`BBB`CCC]
      q)newTbls
      `2020.09.02AAA`2020.09.03BBB`2020.09.04CCC
      q)get each newTbls
      +`colA`colB`date`sym!(,100;,`name;,2020.09.02;,`AAA)
      +`colA`colB`date`sym!(,100;,`name;,2020.09.03;,`BBB)
      +`colA`colB`date`sym!(,100;,`name;,2020.09.04;,`CCC)
      q)get first newTbls
      colA colB date       sym
      ------------------------
      100  name 2020.09.02 AAA
      

      这是否满足您的需求?

      【讨论】:

        【解决方案5】:

        这可能是在黑暗中刺伤,但为什么不创建一个 hdb 而不是所有这些变量 output20191005ABC、output20191006ABC .. 等等,并且假设您想将它们附加到 1 个表中。

        下面我概述了如何创建一个名为outputHDB 的日期分区hdb,它有一个表outputTbl。我通过按日期和符号运行函数然后将这些行更新到磁盘来创建 hdb。

        C:\Users\Matthew Moore>mkdir outputHDB
        C:\Users\Matthew Moore>cd outputHDB
        // can change the outputHDB as desired
        // start q
        
        h:hopen `::6789; // as a demo I connected to another hdb process and extracted some data per sym / date over IPC
        hdbLoc:hsym `$"C:/Users/Matthew Moore/outputHDB";
        
        {[d;sl]
            
            {[d;s]
        
                //output:yourFunc[date;sym];
        
                // my func as a demo, I'm grabbing rows where price = max price by date and by sym from another hdb using the handle h
                output:{[d;s]
                    h({[d;s] select from trades where date = d, sym = s, price = max price};d;s)    
                }[d;s];
                
                // HDB Part
                path:` sv (hdbLoc;`$string d;`outputTbl;`);
                // change `outputTbl to desired table name
                // dynamically creates the save location and then upserts one syms data directly to disk
                // e.g. `:C:/Users/Matthew Moore/outputHDB/2014.04.21/outputTbl/
                // extra / at the end saves the table as splayed i.e. each column is it's own file within the outputTbl directory
                
                path upsert .Q.en[`:.;output];
                // .Q.en enumerates syms in a table which is required when saving a table splayed
        
            }[d;] each sl;
        
            // applies the parted attribute to the sym column on disk, this speeds up querying for on disk data
            @[` sv (hdbLoc;`$string d;`outputTbl;`);`sym;`p#];
            
        }[;`AAPL`CSCO`DELL`GOOG`IBM`MSFT`NOK`ORCL`YHOO] each dateList:2014.04.21 2014.04.22 2014.04.23 2014.04.24 2014.04.25; 
        
        Now that the hdb has been created, you can load it from disk and query with qSQL
        
        q)\l .
        
        q)select from outputTbl where date = 2014.04.24, sym = `GOOG
        
        date       sym  time                          src price size
        ------------------------------------------------------------
        2014.04.24 GOOG 2014.04.24D13:53:59.182000000 O   46.43 2453
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-08
          • 1970-01-01
          相关资源
          最近更新 更多