How to sum multiple elements from single record

2019-08-08 18:29发布

问题:

I have table trade:([]time:`time$(); sym:`symbol$(); price:`float$(); size:`long$()) with e.g. 1000 records, with e.g. 10 unique syms. I want to sum the first 4 prices for each sym.

My code looks like:

priceTable: select price by sym from trade;
amountTable: select count price by sym from trade;
amountTable: `sym`amount xcol amountTable;
resultTable: amountTable ij priceTable;

So my new table looks like: resultTable

sym    | amount price  
-------| --------------------------------------------------------------
instr0 | 106    179.2208 153.7646 155.2658 143.8163 107.9041 195.521 ..

The result of command: res: select sum price from resultTable where i = 1:

price                                                                 
..
----------------------------------
14.71512 153.2244 154.1642 196.5744

Now, when I want to sum elements I receive: sum res

price| 14.71512 153.2244 154.1642 196.5744 170.6052 61.26522 45.70606
46.9057..

When I want to count elements in res: count res

1

I assume that res is a single record with many values, how can I sum all of those values, or how can I sum first for?

回答1:

You can use "each" to run the sum on each row:

select sum each price from res

Or if you want to run on resoultTable:

select sum each price from resoultTable

To sum the first four prices for each row, use a dyadic each-right:

select sum each 4#/:price from resoultTable

Or you could do all of this very easily, in one step:

select COUNT:count i, SUM:sum price, SUM4:sum 4#price by sym from trade


回答2:

 q)trade:([]time:10?.z.d; sym:10#`a`b`c; price:100.+til 10; size:10+til 10)

One caveat with take (#) operator is, if the elements in the list are lesser than the take count , it treats the list as circular and start retruning the repetative results. E.g. check out the 4th price for symbol b and c.

 q)select 4#price by sym from trade
 sym| price
 ---| ---------------
 a  | 100 103 106 109
 b  | 101 104 107 101    //101 - 2 times
 c  | 102 105 108 102    //102 - 2 times

Using sublist can ensure that it the elemnts are lesser than passed count argument , it will just return the smaller list.

 q)select sublist[4;price] by sym from trade
 sym| price
 ---| ----------------
 a  | 100 103 106 109f
 b  | 101 104 107f
 c  | 102 105 108f


标签: kdb