Обновление столбца в таблице KDB на основе состояния нескольких столбцов в таблице - PullRequest
0 голосов
/ 26 февраля 2020

Когда все столбцы (d1; d4) = "N C" для каждой пары, я ищу обновить корректировку до "NO ADJ"

В приведенном ниже случае только первая строка удовлетворяет условию и должно быть обновлено

t:flip (`pair`d1`d2`d3`d4`vol`adjustment)!(`pair1`pair2`pair3`pair4;("NC";"3/-0.09";"1/-0.09";"NC");("NC";"4/-0.09";"-1/-0.09";"NC");("NC";"2/-0.09";"1/0.09";"2/0.3");("NC";"4/-0.09";"0/-0.09";"NC");0 89.68 78.3 0;("0.1bp";"0.1bp";"0.1bp";"0.1bp"))

Заранее спасибо!

Ответы [ 5 ]

4 голосов
/ 26 февраля 2020

Хотя ответ Элиота совершенно верен для вопроса по номиналу. Если у вас много столбцов с именем, например «d *», вы можете обобщить эту форму, и она проверит все столбцы (d1, d2, ..., dn) на «N C».

![`t;{(like;x;"NC")}each ((cols t) where (cols t) like "d*");0b;(enlist `adjustment)!enlist (enlist;"NO ADJ")]

В этом обновлении каждый столбец принимается как «d *», и если все столбцы имеют значение «N C», оно изменит настройку на «NO ADJ» в соответствии с запросом.

Этот оператор обновления может быть изменен по мере необходимости для различных групп столбцов.

Редактировать: Как следует из комментария Данни, наличие `t at! [` T; ... сделает изменение на месте , Если вы хотите проверить и посмотреть, как это выглядит без изменения таблицы в памяти, то для этой цели подойдет `t на t

1 голос
/ 26 февраля 2020

Пока что все предлагаемые в настоящее время решения дают сбой в случае множественных замен

q)t:100000 # flip (`pair`d1`d2`d3`d4`vol`adjustment)!(`pair1`pair2`pair3`pair4;("NC";"3/-0.09";"1/-0.09";"NC");("NC";"4/-0.09";"-1/-0.09";"NC");("NC";"2/-0.09";"1/0.09";"2/0.3");("NC";"4/-0.09";"0/-0.09";"NC");0 89.68 78.3 0;("0.1bp";"0.1bp";"0.1bp";"0.1bp"))
q)update adjustment:enlist"NO ADJ" from t where all(d1;d2;d3;d4)~\:\:"NC"
'length
  [0]  update adjustment:enlist"NO ADJ" from t where all(d1;d2;d3;d4)~\:\:"NC"
       ^
q)update adjustment:enlist"NO ADJ" from t where all (d1;d2;d3;d4) like\:"NC"
'length
  [0]  update adjustment:enlist"NO ADJ" from t where all (d1;d2;d3;d4) like\:"NC"

q)![`t;{(like;x;"NC")}each ((cols t) where (cols t) like "d*");0b;(enlist `adjustment)!enlist (enlist;"NO ADJ")]
'length
  [0]  ![`t;{(like;x;"NC")}each ((cols t) where (cols t) like "d*");0b;(enlist `adjustment)!enlist (enlist;"NO ADJ")]
       ^

Это потому, что не существует простого способа определить количество строк «NO ADJ» вам нужно подставить.

'length
  [0]  update adjustment:enlist "adfjkl" from t where i in 1 2 3
                                                           ^
q)update adjustment:3#enlist "adfjkl" from t where i in 1 2 3
pair  d1        d2         d3        d4        vol   adjustment
---------------------------------------------------------------
pair1 "NC"      "NC"       "NC"      "NC"      0     "0.1bp"
pair2 "3/-0.09" "4/-0.09"  "2/-0.09" "4/-0.09" 89.68 "adfjkl"
pair3 "1/-0.09" "-1/-0.09" "1/0.09"  "0/-0.09" 78.3  "adfjkl"
pair4 "NC"      "NC"       "2/0.3"   "NC"      0     "adfjkl"
pair1 "NC"      "NC"       "NC"      "NC"      0     "0.1bp"

Лучший способ справиться с этим типом векторной замены - через векторное условное

q)update adjustment:?[&/[{"NC" ~/:x} each (d1;d2;d3;d4)];(count adjustment)#enlist "NO ADJ";adjustment] from t
pair  d1        d2         d3        d4        vol   adjustment
---------------------------------------------------------------
pair1 "NC"      "NC"       "NC"      "NC"      0     "NO ADJ"
pair2 "3/-0.09" "4/-0.09"  "2/-0.09" "4/-0.09" 89.68 "0.1bp"
pair3 "1/-0.09" "-1/-0.09" "1/0.09"  "0/-0.09" 78.3  "0.1bp"
pair4 "NC"      "NC"       "2/0.3"   "NC"      0     "0.1bp"
pair1 "NC"      "NC"       "NC"      "NC"      0     "NO ADJ"

Выполнение этой воли тоже вообще будет отлично.

Изучение моего условного выражения

?[&/[{"NC" ~/:x} each (d1;d2;d3;d4)];(count adjustment)#enlist "NO ADJ";adjustment]

В моем предложении where {"NC" ~/:x} each (d1;d2;d3;d4) создает 4 векторных логических списка, затем я сворачиваю их с помощью & (and) и операции сходимости , чтобы узнать, где выполняются все условия.

Два других компонента - мои заменяющие векторы, они должны быть равной длины . Это условие позволяет избежать ошибок двух других попыток, когда вы не можете узнать количество необходимых замен.

1 голос
/ 26 февраля 2020

Один из способов сделать это

q)t
pair  d1        d2         d3        d4        vol   adjustment
---------------------------------------------------------------
pair1 "NC"      "NC"       "NC"      "NC"      0     "0.1bp"
pair2 "3/-0.09" "4/-0.09"  "2/-0.09" "4/-0.09" 89.68 "0.1bp"
pair3 "1/-0.09" "-1/-0.09" "1/0.09"  "0/-0.09" 78.3  "0.1bp"
pair4 "NC"      "NC"       "2/0.3"   "NC"      0     "0.1bp"
q)update adjustment:enlist"NO ADJ" from t where([]d1;d2;d3;d4)~\:`d1`d2`d3`d4!4#enlist"NC"
pair  d1        d2         d3        d4        vol   adjustment
---------------------------------------------------------------
pair1 "NC"      "NC"       "NC"      "NC"      0     "NO ADJ"
pair2 "3/-0.09" "4/-0.09"  "2/-0.09" "4/-0.09" 89.68 "0.1bp"
pair3 "1/-0.09" "-1/-0.09" "1/0.09"  "0/-0.09" 78.3  "0.1bp"
pair4 "NC"      "NC"       "2/0.3"   "NC"      0     "0.1bp"

Это работает, сначала создав словарь-посредник

q)`d1`d2`d3`d4!4#enlist"NC"
d1| "NC"
d2| "NC"
d3| "NC"
d4| "NC"

, а затем проверяя, равен ли каждый элемент таблицы ([]d1;d2;d3;d4) точно этому словарь

например, похожие на конструкции типа

1 2 3~\:1

В этом случае мы используем тот факт, что вся таблица является списком словарей и, с некоторыми боковое мышление, мы часто можем найти способы использовать этот факт

1 голос
/ 26 февраля 2020

Это должно обеспечить решение для предоставленных вами данных. Вам нужно использовать каждый левый угол, чтобы применить предложение where ко всем столбцам. Это оставит вам список из 4 логических значений, где условие выполняется в каждой строке. Вот почему мы затем используем ключевое слово all aswell, чтобы гарантировать, что мы обновляем только тот результат, который соответствует каждому столбцу.

q)update adjustment:enlist"NO ADJ" from t where all (d1;d2;d3;d4) like\:"NC"
pair  d1        d2         d3        d4        vol   adjustment
---------------------------------------------------------------
pair1 "NC"      "NC"       "NC"      "NC"      0     "NO ADJ"
pair2 "3/-0.09" "4/-0.09"  "2/-0.09" "4/-0.09" 89.68 "0.1bp"
pair3 "1/-0.09" "-1/-0.09" "1/0.09"  "0/-0.09" 78.3  "0.1bp"
pair4 "NC"      "NC"       "2/0.3"   "NC"      0     "0.1bp"
1 голос
/ 26 февраля 2020

Этот оператор обновления будет делать то, что вам нужно:

update adjustment:enlist"NO ADJ" from t where all(d1;d2;d3;d4)~\:\:"NC"

Необходимо два левых, поскольку (d1;...;d4) - это список списка строк. Результатом этого сравнения будет

q)(t`d1;t`d2;t`d3;t`d4)~\:\:"NC"
1001b
1001b
1000b
1001b

, тогда применение ключевого слова all приведет к «squa sh» этих логических значений в один список:

q)all(t`d1;t`d2;t`d3;t`d4)~\:\:"NC"
1000b

Наконец, вам нужно использовать enlist в строке "NO ADJ", иначе будет ошибка длины из-за того, что kdb попытается обновить столбец регулировки попарно для каждого символа в строке "NO ADJ".

...