KDB/Q:如何用空值转置 table

KDB/Q: how to transpose a table with null values

我有一个带有 2 个键控列的 table。看起来像这样

date        sym   type  val
2020.01.02  ABC         100
2020.01.02  ABC   a2    200
2020.01.02  ANX         300
2020.01.02  XYZ   a3    400
2020.01.02  XYZ   a2    100

请注意,type 列有一些空值。我想将 table 转置为

date        sym     type_null   type_a2     type_a3
2020.01.02  ABC     100         200         0
2020.01.02  ANX     300         0           0
2020.01.02  XYZ     0           100         400

请注意,如果 type 为空,我们将其设为 0。我可以通过 update type_a2:?[type_a2=0n;0;type_a2] 一旦 table 被转置。有没有更优雅的方法来做到这一点?

关于转置,我不知道该怎么做。我尝试了以下但没有用。

P:asc exec distinct type from myTable;
pvt:exec P#(type!val) by date,sym from myTable;

我认为您可能遇到的问题是命名列 type。关键字或错误类型不能用于变量赋值,因此您可能需要更改它。

就实际代码而言,更改列名后这对我来说似乎工作正常。

q)myTable:([]date:2020.01.02;sym:`ABC`ABC`ANX`XYZ`XYZ;typ:``a2``a3`a2;val:100 200 300 400 100)
q)P:`$"type_",/:asc exec string distinct typ from myTable
q)0!0^exec P#((`$"type_",/:string[typ])!val) by date,sym from myTable
date       sym type_ type_a2 type_a3
------------------------------------
2020.01.02 ABC 100   200     0
2020.01.02 ANX 300   0       0
2020.01.02 XYZ 0     100     400

我在这里使用 0^ 来用 0 填充 table 的所有空条目,并使用 0! 取消 table.[=14= 的密钥]

请注意,将列命名为关键字不是好的做法(您将失去使用 qSQL 的能力),但您仍然可以使用函数形式解决它:

q)table:flip `date`sym`type`val!(2020.01.02;`ABC`ABC`ANX`XYZ`XYZ;``a2``a3`a2;100 200 300 400 100)
q)parse"update `null^type from table"
!
`table
()
0b
(,`x)!,(^;,`null;@:)
q)table:![table;();0b;enlist[`type]!enlist(^;enlist`null;`type)]
q)P:`$?[table;();();(string;(distinct;`type))]
q)0!0^?[table;();{x!x}`date`sym;(#;`P;(!;`type;`val))]
date       sym null a2  a3
---------------------------
2020.01.02 ABC 100  200 0
2020.01.02 ANX 300  0   0
2020.01.02 XYZ 0    100 400
q)`date`sym`type_null`type_a2`type_a3 xcol 0!0^?[table;();{x!x}`date`sym;(#;`P;(!;`type;`val))]
date       sym type_null type_a2 type_a3
----------------------------------------
2020.01.02 ABC 100       200     0
2020.01.02 ANX 300       0       0
2020.01.02 XYZ 0         100     400

将解析应用于作为字符串编写的 qSQL 语句将 return 函数形式的内部表示。

更通用的数据透视函数 (here) 开箱即用,甚至可以与名为 type 的列一起使用....尽管正如其他人所说,您绝对应该避免使用名为 type 的列。

q)myTable:flip`date`sym`type`val!(5#2020.01.02;`ABC`ABC`ANX`XYZ`XYZ;``a2``a3`a2;100 200 300 400 100)
q)0^piv[myTable;`date`sym;1#`type;`val;{`$raze each"type_",/:string`null^y};{x,z}]
date       sym| type_null type_a2 type_a3
--------------| -------------------------
2020.01.02 ABC| 100       200     0
2020.01.02 ANX| 300       0       0
2020.01.02 XYZ| 0         100     400