1

数値を格納する json 配列に対してベクトル演算操作を実行したいと思います。要するに、jq を使用して 1 対 1 の算術演算を実現するにはどうすればよいでしょうか?

「マップ」フィルターで何かを試しましたが、期待どおりの結果が得られませんでした。

jq 'map(one-to-one)' <<< "{\"a\":[1,2], \"b\":[3,4]}"

また

jq 'map(one-to-one)' <<< "[[1,2],[3,4]]"

生成する必要があります

[3,8]
4

2 に答える 2

1

このタイプの問題では、ジェネリック関数を定義するのが理にかなっています。

# Input is assumed to be an array of two numeric arrays of the same length
def pairwise: transpose | map(.[0] * .[1]);

これをさまざまな方法で簡単に使用できるようになりました。

[[1,2],[3,4]] | pairwise

{"a":[1,2], "b":[3,4]} | [.a,.b] | pairwise

{"a":[1,2], "b":[3,4]} | [.[]] | pairwise

これらの場合のそれぞれの結果はもちろん[3,8]です。

効率

非常に大きな入力の場合、次のことを避ける価値があるかもしれませんtranspose:

def pairwise:
   .[0] as $x | .[1] as $y 
   | reduce range(0; $x|length) as $i ([]; . + [$x[$i] * $y[$i]]);

通常、ベクトルの場合、内積に関心があります。これは、効率のために、次のように直接定義するのが最適です。

def inner($a; $b):
  reduce range(0;$a|length) as $i (0; . + $a[$i]*$b[$i]);
于 2019-09-13T09:07:17.243 に答える