2016-10-01 7 views
3

集計関数sum(x)、avg(x)、max(x)、min(x) は、xが空の場合、またはNULL値のみを含む場合はNULLを返します。KDBでNULLを返す集計関数の取得

KDBでは、sumとavgはゼロを返しますが、maxとminは無限大を返します。

(A)ヌルを外し、通常の

nsum:{[x] x: x where not null x; $[0=count x; 0N; sum x]} 

として集計する前に結果が空であるかどうかを確認(:

は、私は2つのオプションが出ているnullを返すの所望の動作を取得するにはB)累積する前にヌルの各項目をチェックする新しい集計を作成する
空のリストを確認する必要があることに注意してください。

nsum:{[z] $[0=count z; 0N; {[x;y] $[null x; y; null y; x; x+y]}/ z ]} 

AまたはBよりも優れた(高速かつ/またはより便利な)方法がありますか?

方法(B)は方法(A)よりも優れていますか?

方法(A)は、任意の集約関数のために働く利点があります。 メソッド(B)は、 "average"に対して機能しません。これは、実行平均を生成するペアワイズ関数 が存在しないためです(すでに適用されている項目の数を知る必要があります)。

関連する質問:0= type first xのように、空のリストが0=count xより速くチェックされていますか?

感謝!

答えて

2

all演算子を使用できます。また、リストの型に基づいてnullを返すこともできます(おそらく)。

f:{$[all null x;(neg type x)$"";sum x]} 
q)f `int$() 
0N 
q)f 0n 0n 0n 0n 
0n 

はパフォーマンスが \t(タイマー)または \ts(時間と空間)を使用し測定します。 http://code.kx.com/q/ref/syscmds/#t-timer

f1:{$[all null x;(neg type x)$"";sum x]} 
fa:nsum:{[x] x: x where not null x; $[0=count x; 0N; sum x]} 
fb:{[z] $[0=count z; 0N; {[x;y] $[null x; y; null y; x; x+y]}/[z] ]} 

allnull:1000000#0N 
withnull:10000000?(1000#0N,til 10) 
withoutnull:10000000?10 

\ts do[10;f withnull] 
612 16777504 
.. 
.. 

方法B(fb)が最も遅いことがわかります。 f1はfaより速く(すべてのリストの場合、速度は同等です)、スペースを少なくします。

2

min/maxの場合、nullを返すようにint/longリストで1を加算したり減算したりしてトリッキーを行うことができます。これは最近Attila VrabeczによってkxCon2016で言及されました。これは、「番号行」にnullと無限がどのように/どこに現れるかの操作です。これらはあまり一般的ではなく、各操作に固有です。

q)a:`int$() 
q)b:1 2 3i 
q)c:0N 0Ni 

q)-1+max 1+a 
0N 
q)-1+max 1+b 
3 
q)-1+max 1+c 
0N 

q)1+min a-1 
0N 
q)1+min b-1 
1 
q)1+min c-1 
0N