我需要维护大约十几张纸,我们希望在其中获得运行加权平均值,并且权重随着时间的推移而衰减:
A | B | C | |
---|---|---|---|
1 | 价值观 | 重量 | AVG |
2 | 6 | 29.63% | 6 |
3 | 3 | 44.44% | 4.2 |
4 | 2 | 66.67% | 3.16 |
5 | 4 | 100.00% | 3.51 |
值是根据过滤器从另一张工作表中提取的。
权重是通过提高行的百分比来生成的:
B5 = (2/3)^0
B4 = (2/3)^1
B3 = (2/3)^2
B2 = (2/3)^4
(简化)代码为
=ARRAYFORMULA(IF(A2:A="","",POW($D$1,$D$2-(ROW(A2:A)-1))
,其中 D1 = 2/3 且 D2 = COUNT(A2:A))
我的麻烦来自加权平均值。当它不自动扩展时,这是一个非常简单的公式:
=AVERAGE.WEIGHTED(A$2:A2, B$2:B2)
。问题是每次添加值时我都必须向下拖动这个公式。我想做的,类似于权重公式,是将其转换为数组公式。
我知道
AVERAGE.WEIGHTED(values, weights)
只是 SUMPRODUCT(values, weights)/sum(weights)
的简写,而那只是 =MMULT(TRANSPOSE(values), weights)/SUM(weights)
的简写
我发现使用
ROW()<=TRANSPOSE(ROW())
生成矩阵,我可以得到数组公式中的权重平均值:
=ArrayFormula(IF(A2:A="", "", MMULT(
TRANSPOSE((ROW(A2:A5)<=TRANSPOSE(ROW(A2:A5))) * IF(A2:A5="",0,A2:A5)),
B2:B5
)/MMULT(
(ROW(B2:B5)>=TRANSPOSE(ROW(B2:B5))) * 1,
B2:B5
)))
非常接近,因为它打印出加权平均值!不幸的是它有两个问题:
A2:A5
调整为 IF(A2:A5="",0,A2:A5)
并与 B2:B5 相同,但没有成功。它只是给出了错误“函数 MMULT 参数 2 需要数字值。但是 '' 是文本,不能强制为数字。”5
使它们成为列引用来自动展开。电子表格速度慢得像爬行一样。我很确定这是因为 ROW()<=TRANSPOSE(ROW())
正在获取 1000 个空白行并生成 1000*1000 = 一百万个单元矩阵。我尝试添加 FILTER()
但这与 ROW()
不兼容(据我所知)。我希望 1 的答案与 2 的答案相同,因为额外的空白单元格似乎是这两个问题的根源。如何解决空白单元格问题,并使我的数组公式高效?谢谢!
MAP
功能:
=MAP(A2:A,B2:B,LAMBDA(value,weight,IF(OR(value="",weight=""),,AVERAGE.WEIGHTED(A2:value,B2:weight))))