问题描述
免责声明:我是Q语言的新手,请原谅我的愚蠢问题。 我有一个函数目前正在接受2个参数(date; sym)。它可以正常运行1个sym和1天。但是,我需要在多个符号和日期上执行此操作,这将永远永久。 如何创建一个在每个符号和每个日期运行该函数的循环? 在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中实现这一目标的最佳方法是什么?
解决方法
如果您有给定的函数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
)。
如果您的函数需要原子date
和sym
,那么您只需创建一个新函数即可实现
q)bar:{[x;y] foo[x;] each y};
,
datelist:`date$10?10
symlist:10?`IBM`MSFT`GOOG
function:{0N!(x;y)}
{.[function;x]} peach datelist cross symlist
cross将返回符号和日期的所有组合 这是您需要的吗?
,尝试使用两个“双” '
raze function'[datelist]'[symlist]
peach
或each
在这里不起作用。它们不是运算符,而是具有两个参数的匿名函数:each
是k){x'y}
。这就是为什么function each list1 each list2
语句无效,但是function'[list1]'[list2]
起作用的原因。
从阅读您对其他答案的回答后,您正在寻找使用唯一名称保存结果的方法,是吗?看看使用set保存并获取的解决方案。
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!(,2020.09.03;,`BBB)
+`colA`colB`date`sym!(,2020.09.04;,`CCC)
q)get first newTbls
colA colB date sym
------------------------
100 name 2020.09.02 AAA
这符合您的需求吗?
,这可能是黑暗中的一个杀手,但是为什么不创建hdb而不是所有这些变量output20191005ABC,output20191006ABC ..等,并假设您要将它们附加到一张表中。
下面,我概述了如何创建名为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