我有这个价值观:
- 数据集:我的工作表 (AQ4:KK4) 中有一行包含 255 个值。数据集中有一些 0 值。
- 重量:我在另一张表中有一列(L3:L257),也有 255 个值。权重永远不会为 0。
我使用转置作为权重,并尝试将数据集数组转换为其倒数,但失败并出现错误。这是我使用的公式,但我很困惑。当数据集没有 0 时,它有效:
=PRODUCT(SUM(如果(AQ4:KK4<>0,TRANSPOSE(L3:L25),FALSE)),1/SUMPRODUCT(如果(AQ4:KK4<>0,TRANSPOSE(L3:L25),""),1/(如果(AQ4:KK4<>0,AQ4:KK4,""))))
我尝试在网上搜索,但答案很少,而且它们更多地涉及加权算术平均值。
正确的公式是什么?
答案1
我同意前面答案中的分析,但我对新功能并不那么着迷,而且我只在必要时使用它们,所以我更喜欢传统的解决方案。我建议使用以下公式:
=MMULT(--(data<>0),weights)/MMULT(IF(data<>0,1/data,0),weights)
其中data
和weights
代表适当的范围。
答案2
我可能有一个解决您问题的方法,尽管我不确定它在数学上是否正确。如果是这样的话,请随意评论我的帖子。
如您所知,您的问题来自数据集中的 0 值。一种解决方法是从计算中删除这些值。
但这会产生另一个问题:代表权重的数组大小不会相同,因此SUMPRODUCT
会失败。
因此,如果数据集中的权重对应项为零,那么您也需要删除一些权重。
幸运的是,使用数组公式,这很容易做到!您需要以下函数来执行此操作(我建议查看 MS 文档以了解它们的工作原理):
LET
作为一般函数,能够设置可在公式中重复使用的变量HSTACK
水平组合两个数组FILTER
用于过滤数组(可能使用另一个数组)TAKE
并可DROP
用于截断数组
以下是内联形式的公式:
=LET(x, B5:B7, y, D3:F3, xy, HSTACK(x, TRANSPOSE(y)), xy_filtered, FILTER(xy, DROP(xy,, 1)<>0), x_filtered, TAKE(xy_filtered,, 1), y_filtered, DROP(xy_filtered,, 1), PRODUCT(SUM(x_filtered),1/SUMPRODUCT(x_filtered,1/y_filtered)))
以下是用户友好形式的公式:
=LET(
x, B5:B7,
y, D3:F3,
xy, HSTACK(x, TRANSPOSE(y)),
xy_filtered, FILTER(xy, DROP(xy,, 1)<>0),
x_filtered, TAKE(xy_filtered,, 1),
y_filtered, DROP(xy_filtered,, 1),
PRODUCT(SUM(x_filtered),1/SUMPRODUCT(x_filtered,1/y_filtered))
)"
下面是它的工作原理:
- 这
LET
是主函数,用于定义计算中使用的局部变量。为了清晰起见,有些是临时变量。 x
和y
分别是重量范围(垂直)和数据集范围(水平)。您需要用自己的范围替换它们。xy
是由权重列和数据集转置组成的2列矩阵。现在权重和数据集值并排在同一个矩阵中。xy_filtered
是相同的矩阵,但是为零的行y
被过滤掉了。DROP(xy,,1)
用于删除矩阵x
中的列xy
(即删除一行和一列)。换句话说,它代表y
。- 相反,
TAKE(xy,,1)
用于保留矩阵x
中的列xy
(即保留所有行和 1 列) - 由于您的矩阵
xy_filtered
现在没有任何 0 值,因此您可以使用和函数将其拆分回x_filtered
和变量。y_filtered
DROP
TAKE
- 函数的最后一个参数
LET
始终是您返回的内容。因此,我只是添加了您提供的函数,但删除了现在不必要的语句,并用和变量IF
替换了您提供的范围。x_filtered
y_filtered
以下是仅包含 3 个值的示例。我的公式(绿色)返回的值与您的(黄色)相同:
现在如果我们添加一个 0: