Как последовательно суммировать списки значений, содержащихся в таблице? - PullRequest
2 голосов
/ 22 мая 2019

У меня есть следующие две таблицы:

t1:([]sym:`AAPL`GOOG; histo_dates1:(2000.01.01+til 10;2000.01.01+til 10);histo_values1:(til 10;5+til 10));

t2:([]sym:`AAPL`GOOG; histo_dates2:(2000.01.05+til 5;2000.01.06+til 4);histo_values2:(til 5; 2+til 4));

Я хочу суммировать histo_values каждого символа по histo_dates, чтобы полученная таблица выглядела следующим образом:

t:([]sym:`AAPL`GOOG; histo_dates:(2000.01.01+til 10;2000.01.01+til 10);histo_values:(0 1 2 3 4 6 8 10 12 9;5 6 7 8 9 12 14 16 18 14))

Таким образом, итоговые даты histo_dates должны быть объединением histo_dates1 и histo_dates2, а histo_values - суммой histo_values1 и histo_values2 между датами.

РЕДАКТИРОВАТЬ:

Я настаиваю на объединении дат, так как я хочу, чтобы результирующее histo_dates было объединением histo_dates1 и histo_dates2.

Ответы [ 3 ]

4 голосов
/ 22 мая 2019

Есть несколько способов.Можно было бы разгруппировать, чтобы удалить вложение, объединить таблицы, агрегировать по sym / date, а затем перегруппировать по sym:

q)0!select histo_dates:histo_dates1, histo_values:histo_values1 by sym from select sum histo_values1 by sym, histo_dates1 from ungroup[t1],cols[t1]xcol ungroup[t2]
sym  histo_dates                                                                                                   histo_values
-------------------------------------------------------------------------------------------------------------------------------------------
AAPL 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 0 1 2 3 4 6  8  10 12 9
GOOG 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 5 6 7 8 9 12 14 16 18 14

Возможно, более быстрый способ состоял бы в том, чтобы сделать каждую строку словарем, а затем набрать таблицыв sym и добавьте их:

q)select sym:s, histo_dates:key each v, histo_values:value each v from (1!select s, d!'v from `s`d`v xcol t1)+(1!select s, d!'v from `s`d`v xcol t2)
sym  histo_dates                                                                                                   histo_values
-------------------------------------------------------------------------------------------------------------------------------------------
AAPL 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 0 1 2 3 4 6  8  10 12 9
GOOG 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 5 6 7 8 9 12 14 16 18 14

Другой вариант - использование плюсового соединения pj:

q)0!`sym xgroup 0!pj[ungroup `sym`histo_dates`histo_values xcol t1;2!ungroup `sym`histo_dates`histo_values xcol t2]
sym  histo_dates                                                                                                   histo_values
-------------------------------------------------------------------------------------------------------------------------------------------
AAPL 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 0 1 2 3 4 6  8  10 12 9
GOOG 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 5 6 7 8 9 12 14 16 18 14

Подробнее о плюсовых соединениях см. здесь: https://code.kx.com/v2/ref/pj/

РЕДАКТИРОВАТЬ: Чтобы явно убедиться, что результат имеет объединение дат, вы можете использовать объединение объединений:

q)0!`sym xgroup select sym,histo_dates,histo_values:hv1+hv2 from 0^uj[2!ungroup `sym`histo_dates`hv1 xcol t1;2!ungroup `sym`histo_dates`hv2 xcol t2]
sym  histo_dates                                                                                                   histo_values
-------------------------------------------------------------------------------------------------------------------------------------------
AAPL 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 0 1 2 3 4 6  8  10 12 9
GOOG 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05 2000.01.06 2000.01.07 2000.01.08 2000.01.09 2000.01.10 5 6 7 8 9 12 14 16 18 14

0 голосов
/ 23 мая 2019

Другой возможный способ использования функциональных поправок

//Column join the histo_dates* columns and get the distinct dates - drop idx
//Using a functional apply use the idx to determine which values to plus
//Join the two tables using sym as the key - Find the idx of common dates

(enlist `idx) _select sym,histo_dates:distinct each (histo_dates1,'histo_dates2),
            histovalues:{@[x;z;+;y]}'[histo_values1;histo_values2;idx],idx from 
                update idx:(where each histo_dates1 in' histo_dates2) from ((1!t1) uj 1!t2)

Одна из возможных проблем заключается в том, что для получения идентификатора, это зависит от сортируемых столбцов даты, что обычно имеет место.

0 голосов
/ 22 мая 2019

по-другому:

// rename the columns to be common names, ungroup the tables, and place the key on `sym and `histo_dates
q){2!ungroup `sym`histo_dates`histo_values xcol x} each (t1;t2)

// add them together (or use pj in place of +), group on `sym
`sym xgroup (+) . {2!ungroup `sym`histo_dates`histo_values xcol x} each (t1;t2)

// and to test this matches t, remove the key from the resulting table
q)t~0!`sym xgroup (+) . {2!ungroup `sym`histo_dates`histo_values xcol x} each (t1;t2)
1b
...