尝试按平均值聚合,然后根据kdb中的平均值修剪观察异常值

时间:2017-05-18 20:16:04

标签: kdb q-lang

我试图按项目类型找到平均值,然后设置一个取值为的变量y:

  1. 缺少值,如果x = 0,
  2. y = x。然后舍入太大或太小的值:
  3. 如果x> 0,x> mu,然后设y = mu
  4. 如果x< 0,x< mu,然后设y = mu
  5. 这是我尝试过的,不会产生下面所需的结果:

    SELECT v.VEHICLEPLATE, p.NAME
      FROM ITV i, VEHICLE v, BUYS b, PERSON p, CENTER c, WORKER w
      WHERE
       w.NICK = 'PEPE' AND
       c.ID = w.CENTERID AND
       v.VEHICLEPLATE = i.VEHICLEPLATE AND
       v.VEHICLEPLATE = b.VEHICLEPLATE AND
       p.ID = b.PERSON;
    

    期望的结果:

     tab2:([]items:`a`b`a`a`b; x:-6 8 0 -3 5)
     tabsum: select mu:avg x by items from tab2;
     tab2: update y:x from tab2
     tab2: update y:mu from tab2 where x > 0 and x > mu / get error after running above step
     tab2: update y:mu from tab2 where x < 0 and x <= mu
    

    与此数据相关:

    i)NaN是否是kdb中缺失值的合适类型? (例如, items x mu y a -6 -3.0 -3.0 b 8 6.5 6.5 a 0 -3.0 NaN a -3 -3.0 -3.0 b 5 6.5 5 与R中的NANaN不同。我根据我到目前为止所阅读的内容进行猜测。

    ii)是否有更高效的代码来获取NULL内的mu列?制作另一张表并合并我猜不高效(仍在学习kdb的基础知识)

    ⅲ) 如果我只是运行

    tab2

    我明白了:

    tab2:([]items:`a`b`a`a`b; x:-6 8 0 -3 5)
         tabsum: select mu:avg x by items from tab2;
         tab2: update y:mu from tab2 where x > 0 and x > mu
    

    第5行对我没有意义。如果x <1,为什么y = 6.5?亩?我希望那一行y = 5。很明显,我对正在发生的事情的理解是错误的。

    iv)如何​​获得所需的结果(我发布的代码并没有正常工作)

2 个答案:

答案 0 :(得分:3)

这可能不是最漂亮的解决方案,但似乎符合您的标准。我使用向量条件?来设置y的值:

q)show tab3: update y:?[((x>0) and x>mu) or ((x<0) and x<=mu);mu;x] from update mu:avg x by items from tab2
items x  mu  y  
----------------
a     -6 -3  -3 
b     8  6.5 6.5
a     0  -3  0  
a     -3 -3  -3 
b     5  6.5 5

然后将所有y=0值替换为null 0n(而不是NaN):

q)update y:0n from tab3 where y=0
items x  mu  y  
----------------
a     -6 -3  -3 
b     8  6.5 6.5
a     0  -3     
a     -3 -3  -3 
b     5  6.5 5

您最后一行的意外结果是执行顺序; q代码从右到左执行。所以:

5>0 and 5>6.5

实际上意味着:

5>(0 and 5>6.5)

是:

5>0

评估为true。要进行所需的比较,您需要使用括号:

q)(5>0) and 5>6.5
0b

您的代码块无法正常工作的原因有几个。在第2行,您不能使用tab2列更新mu;你只需要创建一个新表。因此,当您尝试在第4行使用mu时,它不存在(这将导致错误)。在第3行,您将y的值设置为与x相同,但这也意味着相同的类型(整数)。然后,当您尝试将y重置为mu的浮点值时,会出现'type错误。

这里有一段类似于你的代码块:

q)tab2:([]items:`a`b`a`a`b; x:-6 8 0 -3 5)
q)tab2: update mu:avg x by items from tab2
q)tab2: update y:"f"$x from tab2
q)tab2: update y:mu from tab2 where (x>0) and (x> mu)
q)tab2: update y:mu from tab2 where (x<0) and (x<= mu)
q)tab2
items x  mu  y  
----------------
a     -6 -3  -3 
b     8  6.5 6.5
a     0  -3  0  
a     -3 -3  -3 
b     5  6.5 5

答案 1 :(得分:1)

您可以在一行中执行此操作:

tab3: update y:?[abs[x]>abs[mu];mu;x] from (update mu:avg x by items from tab2) where x<>0