如何用最近的非空价格平均值填充KDB+表中的空价格字段
用此前非空价格的平均值填充KDB+表的空值
我有一个KDB+表,需要将price字段中的空值替换为该位置之前所有非空价格的平均值。
原始表创建代码
t:([] time: .z.p+til 10) t:update price: rand 50.0 from t where i=0 t:update price: rand 50.0 from t where i=1 t:update price: rand 50.0 from t where i=2 t:update price: rand 50.0 from t where i=4
原始表内容
time price -------------------------------------- 2025.01.13D07:54:49.068012805 20.00 2025.01.13D07:54:49.068012806 25.00 2025.01.13D07:54:49.068012807 30.00 2025.01.13D07:54:49.068012808 2025.01.13D07:54:49.068012809 35.00 2025.01.13D07:54:49.068012810 40.00 2025.01.13D07:54:49.068012811 2025.01.13D07:54:49.068012812 2025.01.13D07:54:49.068012813 30.00 2025.01.13D07:54:49.068012814
预期输出
time price -------------------------------------- 2025.01.13D07:54:49.068012805 20.00 2025.01.13D07:54:49.068012806 25.00 2025.01.13D07:54:49.068012807 30.00 2025.01.13D07:54:49.068012808 25.00 / --> (20+25+30)/3 2025.01.13D07:54:49.068012809 35.00 2025.01.13D07:54:49.068012810 40.00 2025.01.13D07:54:49.068012811 37.50 / --> (35+40)/2 2025.01.13D07:54:49.068012812 37.50 / --> (35+40)/2 2025.01.13D07:54:49.068012813 30.00 2025.01.13D07:54:49.068012814 30.00 / --> (30)/1
解决方案
利用KDB+的scan函数(\操作符)跟踪遍历过程中累计的非空价格总和与数量,遇到空值时用当前累计平均值填充:
t: update price: last each {[acc;p] if[null p; // 空值:保留累计总和、计数,返回平均值 (acc[0]; acc[1]; acc[0] % acc[1]) ] else { // 非空值:更新累计总和、计数,返回原价格 (acc[0] + p; acc[1] + 1; p) } }[(0;0;0)] \ price from t
代码说明
(0;0;0)为初始累计状态:(累计总和; 非空数量; 当前价格)scan(\)会逐个处理price字段元素,每次传递更新后的累计状态- 最后取每个状态的第三个元素(
last each),得到处理后的price列
执行以上代码后,即可得到符合预期的表。
内容的提问来源于stack exchange,提问作者Patryk Maryn
相关产品推荐
相关产品推荐

