如何为KDB+数据表按UID添加后续N个偏差值列?
解决KDB+中按UID生成后续N个偏差值列的问题
原始数据表
date sym uid deviation ----------------------------------- 2021.07.10 788779 107701 2.900847 2021.08.21 791540 107701 0.6709649 2021.09.11 790922 107701 0.326201 2021.09.22 791791 107701 -1.425739 2021.10.05 792719 107701 0.1128322 2021.10.12 793640 107701 1.857719 2021.10.19 793807 107701 1.413592 2021.11.02 795043 107701 -0.7289951 2021.11.11 797765 107701 0.7397986 2021.12.07 798360 107701 1.264232 2022.01.03 800399 107701 -0.2387543 2022.01.08 800469 107701 0.04359242 2022.01.24 801516 107701 -2.409638 2022.02.11 802449 107701 3.579713 2022.02.25 803389 107701 0.4503621 2022.03.09 804335 107701 -0.1587543 2022.03.26 805403 107701 -1.709638 2022.03.29 806461 107701 0.2103621 2022.04.27 808831 107701 0.3603621 2022.06.15 812666 107701 1.18339
需求
为每条记录添加dev1、dev2、dev3三列,分别对应当前uid分组下,当前记录之后的第1、2、3个deviation值;无后续值时自动填充null。预期效果示例:
date sym uid deviation dev1 dev2 dev3 ------------------------------------------------------------------- 2021.07.10 788779 107701 2.900847 0.6709649 0.326201 -1.425739 2021.08.21 791540 107701 0.6709649 ... 2021.09.11 790922 107701 0.326201 ... 2021.09.22 791791 107701 -1.425739 ...
问题场景
已移除by子句中的sym以排除其匹配条件,但执行以下代码后,第一行的dev3仍显示null,而实际该uid后存在第3个值(应为2.138838):
q)t,'flip`dev1`dev2`dev3!flip(update c:1_next\[3;3#deviation,3#0n] by uid from t)`c date sym uid deviation dev1 dev2 dev3 --------------------------------------------------- 2025.04.23 C 1 1.57101 2.068364 1.207089 2025.04.24 A 1 2.068364 1.207089 2025.04.25 B 2 2.063919 3.140132 2.844687 2025.04.26 A 3 1.626657 2.117923 2.766439 2025.04.27 A 0 0.7123354 1.972734 2.314081 2025.04.28 A 1 1.207089 2025.04.29 C 2 3.140132 2.844687 2025.04.30 C 1 2.138838 2.068364 1.207089 2025.05.01 C 2 2.844687 2025.05.02 B 1 1.646388 1.207089 2025.05.03 B 0 1.972734 2.314081 2025.05.04 A 0 2.314081 2025.05.05 B 1 0.3355543 2025.05.06 C 2 0.7839629 3.140132 2.844687 2025.05.07 C 1 1.502552 2.068364 1.207089 2025.05.08 A 2 2.454981 2.844687 2025.05.09 A 3 2.117923 2.766439 2025.05.10 B 3 2.766439 2025.05.11 A 0 0.9186462 1.972734 2.314081 2025.05.12 B 0 2.767812 2.314081 q)
正确实现方法
方法一:直观多次偏移
直接对每个uid分组,使用next函数依次获取后续第1、2、3个值,无值时自动填充null:
update dev1:next deviation, dev2:next next deviation, dev3:next next next deviation by uid from t
方法二:批量生成(支持扩展更多列)
如果需要生成更多后续列(如dev1到devN),可以用批量处理的方式,避免重复写next:
// 定义需要生成的列名 cols:`dev1`dev2`dev3 // 按uid分组,批量生成偏移列 update flip cols!{x next/\:deviation}[1+til count cols] by uid from t
其中1+til count cols生成偏移步数(1、2、3),next/\:deviation对每个步数执行对应次数的偏移操作,最后通过flip转换为列结构。
这两种方法都能正确按uid分组获取后续值,解决原代码中dev3为空的问题。
内容的提问来源于stack exchange,提问作者threedom
相关产品推荐
相关产品推荐

