找出零之前的非零数字的平均值?

时间:2016-01-14 14:55:16

标签: excel formula

我有一个带数字的列,我想计算零之前的所有非零数字的平均值。例如:如果我有一个名为Units的列,我希望在编写公式时填充Average列。

ref

excel中有没有办法使用公式执行此操作?

3 个答案:

答案 0 :(得分:2)

如果你只使用一个辅助列,你可以非常简单地使用公式,如下所示[假设你的数据在A2的A列开始,你的帮助列在B2的B列开始,你的结果将是在C2开始的C列中:

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

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

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

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

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

对于与辅助列中创建的标识符匹配的所有行,这将获取A列中的平均值。

答案 1 :(得分:1)

不像我想的那么简单和短暂,但是,尽管如此,它是:

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

用户定义的工作表函数用作矩阵函数。这意味着您必须选择目标范围(即C2:C12)),输入=myavg(B2:B12)之类的功能,然后按<shift><ctrl><return>。这将把函数用作矩阵函数。

sample worksheet table with matrix function entered

然后该函数将被大括号{}包围,如

matrix function appearance

答案 2 :(得分:1)

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

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

在这种情况下,您只需要输入一个单元格。它将自动上下移动以使范围达到平均值。因此,对于B5,您只需要=special_average(A5)

不过,我会使用等级'Eh'培根的答案。如果禁用宏,它将很快并且也可以工作。

编辑:为了显示公式方式的不同方法(没有辅助列),您可以放入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行,必要时可以扩展)