kdb+中如何对连续的1进行枚举计数?
在kdb+中实现连续1段的递增序列转换
这里提供几种实用的实现方式,针对输入列表中连续的1段生成从1开始的递增序列,0保持不变:
方法一:游程编码(RLE)处理
利用kdb+内置的rle函数拆分连续重复元素,再逐个处理游程后拼接:
l: 0 0 1 1 1 0 0 1 1 res: raze {[v;n] v=1 til[n]+1;0#n} each rle l res / 输出:0 0 1 2 3 0 0 1 2
rle l将原列表转换为游程对:(0;2);(1;3);(0;2);(1;2)- 匿名函数对值为1的游程生成
1到n的序列,值为0的游程生成对应长度的0序列 raze把所有子序列拼接成最终列表
方法二:分组计数
通过标记连续1的分组,再对每个分组内的元素进行位置计数:
l: 0 0 1 1 1 0 0 1 1 groups: 0^l * sums differ not l / 生成连续1段的分组标记,0位置保持0 res: l * {x - first x + 1} each groups group groups res / 输出:0 0 1 2 3 0 0 1 2
differ not l标记元素与前一个是否不同,sums累加后得到分组编号,乘以l过滤掉0的分组groups group groups按分组聚合元素,匿名函数计算每个元素在组内的递增位置,最后乘以原列表保留0的位置
方法三:扫描累加(最简洁)
用scan函数跟踪当前计数,遇到0重置,遇到1递增:
l: 0 0 1 1 1 0 0 1 1 res: 1_res {[prev;curr] curr=0 0;prev+1} scan 0, l res / 输出:0 0 1 2 3 0 0 1 2
scan从初始值0开始遍历列表,遇到0返回0,遇到1则在前一个值基础上加11_res去掉scan返回结果的初始值,得到与原列表长度一致的结果
内容的提问来源于stack exchange,提问作者marital_weeping
相关产品推荐
相关产品推荐

