如何在KDB中按Symbol删除数据行?移除每个sym对应前60行的语句错误排查
问题分析与解决方案
你的语句ungroup 60 _ select from table by sym没有达到预期效果的核心原因是操作对象完全错误:
select from table by sym执行后,会生成一个分组汇总表——每一行对应一个唯一的sym值,原表的常规列会变成嵌套列表(比如date列的值是该sym对应的所有日期组成的列表)。- 此时
60 _是对这个分组表的整体行进行删除操作,也就是删掉前60个不同的sym分组,而不是每个sym分组内部的前60行数据,完全偏离了你“删除每个sym对应的前60行”的需求。
正确的实现方式
要实现“每个sym分组内删除前60行”,你需要在分组内部对行进行过滤,而不是对分组后的表整体操作。推荐两种简洁的写法:
方法1:使用fby分组过滤(最常用)
select from table where i >= 60 fby sym
这里i >= 60 fby sym表示:对每个sym分组,只保留行索引i大于等于60的行(每个分组内的行索引从0开始计数)。如果某个sym的总行数不足60,会被完全过滤掉(符合“删除前60行”的逻辑,因为这类sym本来就没有60行可删)。
方法2:分组后对每个组应用drop操作
如果你需要明确对每个分组执行“删除前60行”的动作(即使分组行数不足60,也保留剩余行),可以用分组后处理的方式:
ungroup select v, ac, lR, zR:60_ each (v;ac;lR;zR) from table group by sym, date
这里group by sym生成以sym为键的分组字典,每个分组是该sym的子表,60_ each ...对每个子表的列执行删除前60行的操作,最后ungroup将嵌套结构展开为普通表。
验证示例
用你提供的小样本数据测试(sym为A的行只有8行,所以方法1会返回空表,因为没有i>=60的行):
table:([]sym:`A`A`A`A`A`A`A`A;date:1999.11.18 1999.11.19 1999.11.22 1999.11.23 1999.11.24 1999.11.26 1999.11.29 1999.11.30;v:4.47399e+07 1.08971e+07 4705200 4274400 3464400 1237100 2914700 3083000;ac:29.11226 26.71712 29.11226 26.6311 27.16703 27.25305 27.87499 27.91469;lR:0n -0.08585502 0.08585502 -0.08907963 0.01992441 0.003161097 0.02256457 0.00142315;zR:0n 0n 1 -0.7267457 0.5031717 0.2454482 0.4784645 0.1285608) // 执行方法1,返回空表(符合预期,因为A只有8行,没有第61行及以后的数据) select from table where i >= 60 fby sym
如果你的实际数据中某个sym有超过60行,这个语句会正确保留第61行及以后的数据。
内容的提问来源于stack exchange,提问作者cjm2671
相关产品推荐
相关产品推荐

