Excel 根据条件计算过滤数据的 运行 平均值

Excel Calculate a running average on filtered data with criteria

我正在尝试计算过滤数据 table 的 运行 平均值。所有其他在线帖子在整个范围内使用 Sumproduct(Subtotal) 但不逐行计算 运行 平均值

我卡在了如何计算 C 列和 D 列上。

如果B栏(得分) > 0,我想在C栏(平均获胜)[=下求和并取平均值19=]

如果B列(得分) < 0,我想在D列(平均损失)[=下求和并取平均值19=]

table 可按 A 列(类型) 过滤,结果应如下所示



目前进度:

我已经弄清楚如何根据过滤后的数据计算累积分数。但是,这并不能完全解决我的问题。感谢您的帮助!

=SUBTOTAL(3,B3)*SUBTOTAL(9,B:B3)

SUBTOTAL(3,B3) 检查当前行是否可见,SUBTOTAL(9,B$3:b3) 求和值。



需要最后更新

Jos - 感谢您详细解释 subtotal() 的工作原理。我通过你的解释学到了很多东西,并将继续研究它。这是我第一次接触结构化引用,所以有些语法对我来说还是有点混乱

我需要的最后一个公式是 运行 win % 列,其中 Win 由分数 > 0 定义。请参见下图

我的假设认为相同的公式会起作用,只是我们在每一行而不是 [Score] 列中取 1 或 0 的平均值。 使用先前的解决方案,为什么我们不能修改您先前解决方案的输出来计算 运行 赢 %?

[...] IF([Score]>0,IF(ROW([Score])<=ROW([@Score]),[Win])))),0)

其中 [Win] 是辅助列,输出 1 表示赢,0 表示输。 这可以通过说

来完成
if([@score]>0,1,0)

这不是对实际的@Score 进行平均,而是对具有所需输出 0%、50%、66% 等的 1 和 0 的列进行平均


我知道我提供的解决方案不起作用,但我正在努力接受正确的逻辑。我仍然很难理解这些结构化列引用是如何逐行计算的。 例如:Average(If([Score]>0,[Score])

这是如何逐行计算的?当 A3 做 If([Score] > 0,) 时,这是否等于 If({-10}>0)?在A4上,If([Score]>0)是否等于If({-10,20} >0)?感谢您迄今为止的耐心等待和帮助。

所以,我会使用 averageifs()。

=averageifs(B:B,B:B,">=1",A:A,"A")

是一个例子,注意我在例子中添加了Type A的控件

参见:

我不同意你未过滤的 table 最后一行的 平均损失 的结果(肯定是 -9.33...?),但试试这个 平均获胜:

=IFERROR(AVERAGE(IF(SUBTOTAL(3,OFFSET(INDEX([Score],1),ROW([Score])-MIN(ROW([Score])),)),IF([Score]>0,IF(ROW([Score])<=ROW([@Score]),[Score])))),0)

平均损失 的相同公式,将 [Score]>0 更改为 [Score]<0

解释:

使用您提供的数据并假设:

  1. table 的左上角单元格位于 A1
  2. table 在“A”的 Type 列上过滤

为了确定过滤了哪些行,我们必须将范围引用数组(即 table 所选列中的每个单元格)传递给 SUBTOTAL 函数。不幸的是,这样的范围引用数组只能通过 volatile 函数(INDIRECTOFFSET)生成,但在这里,除非我们求助于辅助列,否则我们别无选择。

INDEX([Score],1)

只是 returns 对 Score 列中第一个单元格的范围引用。使用 Excel tables 时,最好不要编写包含结构化和非结构化引用混合的公式,即使这会导致表达式稍长一些。所以在这里,例如,我们不会在公式中引用 A2

ROW([Score])-MIN(ROW([Score]))

生成一个整数数组,从 0 到比 table 中的行数少一,即

{0;1;2;3;4}

等等

=IFERROR(AVERAGE(IF(SUBTOTAL(3,OFFSET(INDEX([Score],1),ROW([Score])-MIN(ROW([Score])),)),IF([Score]>0,IF(ROW([Score])<=ROW([@Score]),[Score])))),0)

变成

=IFERROR(AVERAGE(IF(SUBTOTAL(3,OFFSET(A2,{0;1;2;3;4},)),IF([Score]>0,IF(ROW([Score])<=ROW([@Score]),[Score])))),0)

OFFSET 然后生成一个范围引用数组(但请注意,您将无法 'see' 在评估公式 window 中执行此步骤 - 相反,# VALUE!显示错误):

=IFERROR(AVERAGE(IF(SUBTOTAL(3,{A2;A3;A4;A5;A6}),IF([Score]>0,IF(ROW([Score])<=ROW([@Score]),[Score])))),0)

SUBTOTAL然后判断这些范围引用中的哪些被过滤(注意这里必须注意第一个参数的选择),返回相关的布尔值,这样:

SUBTOTAL(3,{A2;A3;A4;A5;A6})

解析为:

{1;1;1;0;1}

所以我们现在有:

=IFERROR(AVERAGE(IF({1;1;1;0;1},IF([Score]>0,IF(ROW([Score])<=ROW([@Score]),[Score])))),0)

剩下的就很简单了。