假设一个 Json 数字数组:
[ 1, 4, 6, 9, 8, 10, 5, 2]
我想计算 3 天移动平均线。结果数组是通过平均前 3 个条目来计算的。
所以前 3 个条目无关紧要,第 4 个是(1+4+6)/3
,第 5 个是(4+6+9)/3
等等。
从概念上讲,这就是我想要做的:
echo '[ 1, 4, 6, ... ]' | jq 'map(average(select(prev 3 array entries)))'
假设一个 Json 数字数组:
[ 1, 4, 6, 9, 8, 10, 5, 2]
我想计算 3 天移动平均线。结果数组是通过平均前 3 个条目来计算的。
所以前 3 个条目无关紧要,第 4 个是(1+4+6)/3
,第 5 个是(4+6+9)/3
等等。
从概念上讲,这就是我想要做的:
echo '[ 1, 4, 6, ... ]' | jq 'map(average(select(prev 3 array entries)))'
这个问题启发了我学习jq,谢谢!
我的解决方案是
'. as $val | to_entries | map((.value + $val[.key-1] + $val[.key-2])/3) | .[2:]'
第一步,将整个数组保存到变量 $val
第二步将数组转换为带有键的对象数组(试试看!,它将您的示例数组转换为
[
{
"key": 0,
"value": 1
},
{
"key": 1,
"value": 4
},
{
"key": 2,
"value": 6
},
{
"key": 3,
"value": 9
},
{
"key": 4,
"value": 8
},
{
"key": 5,
"value": 10
},
{
"key": 6,
"value": 5
},
{
"key": 7,
"value": 2
}
]
)
第三步从每个点获取值并添加前两个步骤的值
最后一步是可选的,它会抛出“你不关心”的值
这是一个 jq 过滤器,它使用递归函数来计算每 n 个元素的移动平均值。
def avg(n):
if length < n then empty # base case
else ( .[0:n] | add/n ) # average of first n elements
, ( .[1:] | avg(n) ) # recursive call
end
;
avg(3)
您可以使用这样的过滤器:
def rolling_average(size): . as $items |
[ range(0;length-size)
| $items[.:.+size]
| add/size
]
;
rolling_average(3)
这个想法是生成索引范围以获得平均值,然后取这些项目的平均值。