英文:
How to calculate weighted average of non-zero values?
问题
我是新手学习Go语言,我正在做以下操作:
我有一个切片:
valueList := []int16{500, 400, 0, 300}
还有一个权重切片:
weightList := []float64{0.1, 0.2, 0.3, 0.4}
现在我想要做的是:
res := make([]float64, 4)
for i, value := range valueList {
res[i] = float64(value) * weightList[i]
}
但是正如你所看到的,我在valueList
中得到了一个0
,现在如果值不是0
,我想要将权重平均分配给其他值,所以在这个例子中,应该是:
500 * (0.1 + 0.3/3) + 400 * (0.2 + 0.3/3) + 300 * (0.4 + 0.3/3)
如果另一个0
出现,再次平均分配权重。
我该如何简单地实现这个功能?
英文:
I am new to Go, I am doing the following:
I have a slice:
valueList := []int16{500, 400, 0, 300}
and a weight slice:
weightList := []float64{0.1, 0.2, 0.3, 0.4}
Now I want to do this:
res := make([]float64, 4)
for i, value := range valueList {
res[i] = float64(value) * weightList[i]
}
But as you can see, I get a 0
in valueList
, now I want to average the weight to the others if value is not 0
, so in this example, it should be:
500 * (0.1 + 0.3/3) + 400 * (0.2 + 0.3/3) + 300 * (0.4 + 0.3/3)
If another 0
shows up, average the weight again.
How can I do this simply?
答案1
得分: 3
你可以在迭代非零值时计算它们的总权重,并在最后通过总权重进行除法运算:
vs := []int{500, 400, 0, 300}
ws := []float64{0.1, 0.2, 0.3, 0.4}
sumWeight, avg := 0.0, 0.0
for i, v := range vs {
if v == 0 {
continue
}
sumWeight += ws[i]
avg += float64(v) * ws[i]
}
avg /= sumWeight
fmt.Println("平均值:", avg)
输出结果(在Go Playground上尝试):
平均值:357.1428571428571
注意:
此解决方案不要求权重总和为1.0
,也不要求在0..1
的范围内(但不能为负)。
注意2:
如果输入切片为空(长度为0
或所有值都为0
),或者非零值的总权重为0.0
,由于除以sumWeight
(即0.0
),结果将为NaN
。你可能想检查这种情况并采取其他措施:
if sumWeight > 0.0 {
avg /= sumWeight
}
英文:
You can calculate the sum weight of non-zero values while iterating over them, and do the division by the sum weight at the end:
vs := []int{500, 400, 0, 300}
ws := []float64{0.1, 0.2, 0.3, 0.4}
sumWeight, avg := 0.0, 0.0
for i, v := range vs {
if v == 0 {
continue
}
sumWeight += ws[i]
avg += float64(v) * ws[i]
}
avg /= sumWeight
fmt.Println("Average:", avg)
Output (try it on the Go Playground):
Average: 357.1428571428571
Note:
This solution does not require weights to sum up to 1.0
neither to be in the range of 0..1
(but they can't be negative).
Note #2:
If the input slices are empty (either by having len == 0
or all values being 0
) or sumWeight
of non-zero values is 0.0
, the result will be NaN
due to dividing by sumWeight
which is 0.0
. You might want to check this case and do something else:
if sumWeight > 0.0 {
avg /= sumWeight
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论