我是kdb + q的新手。我在我的一个练习中遇到了以下涉及表格的问题。
给定一个带有单个key = id的键控表t,写一个返回另一个表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。
我尝试编写一些函数但是访问每一行并处理空值一直是个麻烦。
任何人都可以帮我吗?
答案 0 :(得分:1)
这就是我所说的:
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
答案 1 :(得分:1)
这是我的尝试,但明显慢于@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
答案 2 :(得分:0)
这将照顾类型(我会花一些时间并对其进行优化)
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