我正在尝试找到
k
:下表a
中包含的列表t
中的局部最大值和最小值。此外,我想根据 a
对最小值和最大值进行排名,但仅相对于其他最大值和最小值,如下所示。
我的
relMinMax
方法虽然正确且没有循环,但很冗长,我怀疑其他地方还有更简洁和更快的方法。因此,我想知道是否有更有效和/或更惯用的方法q
?
a:1 0 2 2 3 2 1;
tm:2024.01.01+til count a;
t:([] time:tm; a:a);
relMinMax:{[t]
t:update k:1 from t where ((a>prev a) and (a>next a)); // find relative maxima
t:update k:neg[1] from t where ((a<prev a) and (a<next a)); // find relative minima
t:update k:0 from t where i=first i; // ensure first row is not a maxima or minima
t:update k:0^k from t;
r:select from t where k<>0;
r:update k:k*(1+rank a) from r;
t:delete k from t;
t:0!(`time xkey t) lj (`time xkey r);
t:update k:0^k from t
};
show r:relMinMax t;
time a k
---------------
2024.01.01 1 0
2024.01.02 0 -1
2024.01.03 2 0
2024.01.04 2 0
2024.01.05 3 2
2024.01.06 2 0
2024.01.07 1 0
这并不像我想要的那么干净,但它是你的单行版本
q)update k:{0^(update r:b*1+rank x from([]x;b:+[1*(x>p)&x>n;-1*(x<p:0W^prev x)&x<n:next x])where 0<>b)`r}a from t
time a k
---------------
2024.01.01 1 0
2024.01.02 0 -1
2024.01.03 2 0
2024.01.04 2 0
2024.01.05 3 2
2024.01.06 2 0
2024.01.07 1 0
肯定有一种更清洁的方法......