求助:如何在KDB中编写nprev函数获取当前元素的前n个全部元素
没问题,我来帮你实现KDB中获取每个元素前n个全部元素的函数!你提到的xprev确实只能返回第n个前序元素,而我们需要的是当前元素之前的n个元素组成的列表(不足n个时返回现有元素,没有则返回空列表)。
方法一:用window函数实现(简洁版)
这是最简洁的写法,利用KDB内置的滚动窗口函数来快速实现需求:
// 定义nprev函数:参数n为要取的前序元素个数,col为目标列 nprev:{[n;col] {x except last x} each window[1+n;col]}
测试示例
用你提供的表来验证效果:
// 初始化示例表 t:([] i:1+til 26; s:.Q.a) // 更新表,添加前3个元素的列xp update xp:nprev[3;]s from t
逻辑解释
window[1+n;col]:生成大小为n+1的滚动窗口,每个窗口包含当前元素和它前面的n个元素(窗口不足大小时,只包含已有的元素)。{x except last x} each:对每个窗口去掉最后一个元素(也就是当前元素本身),剩下的就是当前元素的前n个全部元素。
方法二:用prev迭代实现(直观版)
如果你想更清晰地理解底层逻辑,可以用prev函数的迭代来实现:
nprev:{[n;col] // 生成n个prev层级的列:分别存储前1个、前2个...前n个元素 prev_cols:prev\[col] take n; // 转置后过滤每行的null值,得到有效前序元素列表 flip {x where not null x} each flip prev_cols }
逻辑解释
prev\[col] take n:通过迭代prev函数n次,得到一组列,分别对应每个位置的前1个、前2个……前n个元素。flip将列集合转置为行集合,每一行对应原表的一行,包含该位置的前1到n个元素。{x where not null x} each:过滤掉每行中的null值,确保前面的行只返回实际存在的前序元素(比如第1行没有前序元素,返回空列表)。
效果展示
执行完更新后,查看前5行的结果:
5#update xp:nprev[3;]s from t i s xp --------- 1 a () 2 b ,a 3 c a,b 4 d a,b,c 5 e b,c,d
可以看到,每行的xp列都准确返回了当前元素的前3个全部元素,不足3个的则返回现有元素,完全符合你的需求。
内容的提问来源于stack exchange,提问作者user9582902
相关产品推荐
相关产品推荐

