find一个零之前的非零数字的平均值?

我有一个数字列,我想计算在零之前的所有非零数字的平均值。 例如:如果我有一个名为单位的列,我会期望填写公式的平均值列。

Units Average 32 32 33 32 31 32 0 0 0 0 1 2 2 2 3 2 0 0 1 1.5 2 1.5 

有没有办法在Excel中执行这个使用公式?

如果你只使用一个助手字段,你可以简单地用公式来做到这一点,如下[假设你的数据在A列开始于A2,你的帮助者列在B列开始于B2,你的结果将在列C从C2开始]:

帮助栏[放入B2并向下拖动]:

 =IF(A2=0, "", IF(A1=0,MAX(B$1:B1)+1,B1)) 

这会创build一个唯一的标识符,每次在A列中有一个非零值,并且上面的行中的值为0时,向上迭代1次。即:一组行将具有相同的ID号,直到一个0出现 – 然后下一个数字块将有一个高于最后一个组的ID号码。 请注意,B2将需要硬编码为1,否则使A1等于0。

[C2中的结果列并向下拖动]:

 =AVERAGEIFS(A:A,B:B,B2) 

这将在列A中获得与在助手列中创build的标识符匹配的所有行的平均值。

不像我想要的那么简单和短暂,但是,在这里它是:

 Option Base 1 Function myavg(r As Range) Dim i%, i0%, j%, n%, ia, a, oa() ia = r n = UBound(ia, 1) ' get number of rows ReDim oa(n, 1) ' prepare an output array with same no of rows a = 0: i0 = 0 ' a: accumulator summing up values ' i0: position of last 0 value found For i = 1 To n ' go through all input rows If (ia(i, 1) = 0) Then ' current value is zero: oa(i, 1) = 0 ' set output value to 0 If i > i0 + 1 Then a = a / (i - i0 - 1) ' calculate average value of previous group For j = i0 + 1 To i - 1 ' and assign it to output array oa(j, 1) = a Next j a = 0 ' reset the accumulator End If i0 = i Else a = a + ia(i, 1) ' add to accumulator End If Next i If i > i0 + 1 Then ' do average calculation for last group a = a / (i - i0 - 1) ' if it was not ended with a 0 value For j = i0 + 1 To i - 1 oa(j, 1) = a Next j End If myavg = oa End Function 

用户定义的工作表函数用作matrix函数。 这意味着您将不得不select目标范围(即C2:C12) ),input函数如=myavg(B2:B12) ,然后按<shift><ctrl><return> 。 这将把函数作为一个matrix函数。

带有矩阵功能的示例工作表表格

该函数将显示为大括号括起来

矩阵功能外观

只是为了展示一个完全不同的方法:

 Public Function special_average(rng As Range) If rng.Value = 0 Then special_average = "": Exit Function Dim i As Long, lower_rng As Range, str As String Set lower_rng = rng If rng.Row > 1 Then str = rng.Offset(-1, 0).Text While str <> "0" And Len(str) > 0 And IsNumeric(str) And rng.Row > 1 Set rng = rng.Offset(-1, 0) str = rng.Offset(-1, 0).Text Wend If lower_rng.Row < Rows.Count Then str = lower_rng.Offset(1, 0).Text Else str = "" While str <> "0" And Len(str) > 0 And IsNumeric(str) And lower_rng.Row < Rows.Count Set lower_rng = lower_rng.Offset(1, 0) str = lower_rng.Offset(1, 0).Text Wend special_average = Application.WorksheetFunction.Average(rng.Parent.Range(rng, lower_rng)) End Function 

在这种情况下,你只需要input一个单元格。 它会自动上下来得到平均范围。 所以对于B5你只需要=special_average(A5)

不过,我会用“Eh”培根的答案。 如果macros被禁用,它将很快并且也可以工作。

编辑:要显示一个不同的方法来公式的方式(没有帮手列),你可以把B2 ,然后复制下来:

 =IF(A2=0,"",IF(ISNUMBER(B1)*(B1<>0),B1,IFERROR(AVERAGE(OFFSET(A2,0,0, MATCH(0,A2:A1000,0)-1)),AVERAGE(A2:A1000)))) 

缺点是,你需要设置一个最大范围(在这个例子中999行,如果需要可以扩展)