kdb:如何将字典列表转换成一个表,其列是字典键的并集?

时间:2020-12-28 18:09:33

标签: string dictionary kdb

我在下面有一个字符串列表。这是一个简单的例子,只有 3 个字符串,每个字符串包含一些键和它们对应的值。例如,字符串 1 表示到期年份为 2024,出生年份为 1947,发行年份为 2015,身高为 150 厘米等。

show q4
"eyr:2024 pid:662406624 hcl:#cfa07d byr:1947 iyr:2015 ecl:amb hgt:150cm"
"iyr:2013 byr:1997 hgt:182cm hcl:#ceb3a1 eyr:2027 ecl:gry cid:102 pid:018128"
"hgt:61in iyr:2014 pid:916315544 hcl:#733820 ecl:oth"

在另一个线程中,terrylynch 向我解释说我可以使用内置的 kdb/q 函数将键值对提取为字典 kdb/q: How to apply a string manipulation function to a vector of strings to output a vector of strings?

dict: each["S: "0:] q4

dict[0]
eyr    pid         hcl       byr    iyr    ecl   hgt
"2024" "662406624" "#cfa07d" "1947" "2015" "amb" "150cm"

然后我尝试将其转换为表格。从概念上讲,我知道 kdb/q 表基本上是翻转的字典,我知道表的行基本上只是字典。

t: flip dict

show t
`eyr`pid`hcl`byr`iyr`ecl`hgt                               `iyr`byr`hgt`hcl`e..
("2024";"662406624";"#cfa07d";"1947";"2015";"amb";"150cm") ("2013";"1997";"18..

show t[0]
`eyr`pid`hcl`byr`iyr`ecl`hgt
`iyr`byr`hgt`hcl`eyr`ecl`cid`pid
`hgt`iyr`pid`hcl`ecl

show t[1]
("2024";"662406624";"#cfa07d";"1947";"2015";"amb";"150cm")
("2013";"1997";"182cm";"#ceb3a1";"2027";"gry";"102";"018128")
("61in";"2014";"916315544";"#733820";"oth")

这里的问题是上表的每一行都有不同的列。我如何让这个表看起来像下面这样,其中表列是所有键的联合,而一行缺少一个键的值,它只显示为空?

show ideal_t
eyr   iyr    pid        cid..
---------------------------..
2024  2015   662406624  0n ..
2027  2013   018128     102..

谢谢!

3 个答案:

答案 0 :(得分:2)

如果许多字典共享密钥,这里是性能更高的解决方案,因为 uj 在大型输入列表上的性能不是很好。该解决方案利用了以下事实:符合标准的字典列表(相同顺序的相同键)会自动解释为 kdb 中的表。

通过将具有相同键的 n 个字典组合在一起,我们最终得到 m 个表,其中 m 作为唯一键集的数量在字典上。使用 group 还允许我们跳过登记每个字典。

然后我们可以使用 Terry 建议的 (uj/) 解决方案将这些 m 个不同的表连接在一起,但是它只会运行 m 次而不是 n 次。 uj 还确保添加到每个表的空值类型正确。

然后,我们在索引列表(group 返回)上使用 iasc 恢复原始排序。

{uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict

在不同的输入长度上使用这两个函数的一些性能统计数据。 \ts 的输出定义为 here。当不同集的数量较少时,线性缩放

dict:n#dict (taking your input and extending it to n rows - m is always 3)

n = 1000, m = 3    
q)\ts (uj/) enlist each (!) ./: dict
27 519472

\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
1 304480


n = 10000, m = 3    
q)\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
10 3169504

q)\ts (uj/) enlist each (!) ./: dict
1150 6016432


n = 100000, m = 3
q)\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
72 37308384


n = 1000000, m = 3
q)\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
504 308049376

在最坏的情况下,每个字典都有一组不同的键,n=m 并且解决方案收敛到 Terry 的答案,其中应用了 uj n

dict:flip ((enlist each neg[n]?`3);n#enlist enlist "test")

n=m=100
q)\ts (uj/) enlist each (!) ./: dict
9 308064

q)\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
8 318064


n=m=1000
q)\ts (uj/) enlist each (!) ./: dict
1803 24594240

q)\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
1631 24683344


n=m=2000
q)\ts (uj/) enlist each (!) ./: dict
15777 97955584

q)\ts {uj/[x idx] iasc raze idx:value group key each x} (!) ./: dict
16443 98133264

正如 Jason 提到的,您可以提取一组键并从每个字典中提取它们,这将自动变成一个表(如第一段所述),但是当您有不同类型的不同键时,需要小心被带走。

用 d 索引到下面的第一个字典会返回一个整数 null,但第二个字典中的 d 是一个短整数。结果,列将被混合。

/ a dictionary containing an integer, long and float. Missing keys will return integer nulls
q)(`a`b`c!(1i;2j;3f))[`d]
0Ni
/ Two dictionaries, the first containing a and the second d. Both columns end up mixed
q)dict:((`a`b`c;(1i;2j;3f));(`b`c`d;(4j;5f;6h)))
q){(distinct raze x[;0])#/:(!)./:x}dict
a  b c d  
----------
1i 2 3 0Ni
0N 4 5 6h 

uj 会自动考虑这一点,并在调用 .Q.ff 时确保缺失的键值为正确的 null。

答案 1 :(得分:1)

同样,这可能是您原始主题的后续问题!

但是在这里回答:解析每个字段后,您可以使用 (!/) 转换为字典,并使用 enlist 提升为表。那么这只是一个联合加入 uj 每个迭代的问题

q)(uj/)each[enlist(!/)"S: "0:] q4
eyr    pid         hcl       byr    iyr    ecl   hgt     cid
--------------------------------------------------------------
"2024" "662406624" "#cfa07d" "1947" "2015" "amb" "150cm" ""
"2027" "018128"    "#ceb3a1" "1997" "2013" "gry" "182cm" "102"
""     "916315544" "#733820" ""     "2014" "oth" "61in"  ""

答案 2 :(得分:0)

您可以通过从每个字典中“获取”必要的键来避免使用联合连接

q)d:{(-10?`1;10?0N 4#.Q.a)}@'til 10000
q){(distinct raze x[;0])#/:(!)./:x}d
e      o      i      j      f      n      l    ..
-----------------------------------------------..
"qrst" "abcd" "ijkl" "efgh" "ijkl" "efgh" "ijkl..
""     "ijkl" ""     ""     "abcd" "uvwx" ""   ..
"qrst" ""     "uvwx" ""     "ijkl" "yz"   ""   ..
""     "yz"   ""     "abcd" "uvwx" "qrst" "ijkl..
""     "uvwx" ""     "efgh" "yz"   "uvwx" "qrst..
..
相关问题