Изменять строки таблицы в соответствии с нулевыми значениями

Я новичок в kdb + q. Я столкнулся с следующей проблемой, связанной с таблицами в одном из моих упражнений.

Учитывая таблицу с ключом t с единственным ключом = id, напишите функцию, которая возвращает другую таблицу T такую, что:

a) Для каждой строки из t в T существует столько строк, сколько ненулевых значений в этой строке t.

b) Каждая строка в T содержит ровно одно ненулевое значение, которое должно быть таким же, как соответствующее ненулевое значение в t.

Примеры:

If t is

id |a b
----------
1 |1 1
2 |1 0n

then T would be

id | a b
-----------
1 |1 0n
1 |0n 1
2 |1 0n

and if t is
id | a b c
------------------ 
1 | 1 3 0n
2 | 2 0n 4
3 | 0n 0n 5

then T would be

id |a b c
----------------
1 |1 0n 0n
1 |0n 3 0n
2 |2 0n 0n
2 |0n 0n 4
3 |0n 0n 5

Из того, что я вывел из вопроса, если рассматривать каждую строку как n-кортеж, она проецирует вектор вдоль каждого из его n измерений, где 0n ведет себя как 0 в обычном декартовом векторе.

Я попытался написать некоторые функции, но доступ к каждой строке и уход за нулями был проблемой.

Кто-нибудь может мне с этим помочь?

3 ответа

Это то, что я вышел:

q)f
{ungroup x{(x*y)@\:where not null get x}\:{(x;x)#1,x#0N}count[cols x]-1}
q)t:([id:1 2 3]a:1 2 0N;b:3 0N 0N;c:0N 4 5)
q)t
id| a b c
--| -----
1 | 1 3
2 | 2 4
3 | 5
q)f t
id a b c
--------
1 1
1 3
2 2
2 4
3 5


Этот будет заботиться о типах (я потрачу некоторое время и оптимизирую его)

q)t:([ id: 1 2] a: 1 1;b:1 0n;c: 0N 0Ni) //checkout the meta
id| a b c
--| -----
1 | 1 1
2 | 1

q)f:{[t] ungroup {st:count[x]#0#enlist x;d:(enlist each key[x])!'(enlist each value[x]); key[x]!flip r where not all each null each r:value each upsert'[st;d]} each t }

q)f[t]
id a b c
--------
1 1
1 1
2 1

q)meta f[t]
c | t f a
--| -----
id| j
a | j
b | f
c | i


Здесь моя попытка, но значительно медленнее, чем @WooiKent Lee. Я испортил сортировку и удалил полностью нулевые строки (но главным образом с первым).

q)breakout:{k xasc n where any each not null v#n:(0#x0) upsert/((k:keys x),/:v:cols value x)#\:x0:0!x}
q)breakout t
id a b c
--------
1 1
1 3
2 2
2 4
3 5

licensed under cc by-sa 3.0 with attribution.