Рассчитать скользящее среднее в Excel - PullRequest
2 голосов
/ 12 марта 2011

Я хочу вычислить скользящее среднее из последних, скажем, 20, чисел столбца.Проблема в том, что некоторые ячейки столбца могут быть пустыми, их следует игнорировать.Пример:

 A
175
154

188
145
155

167
201

Скользящая средняя из последних трех будет (155 + 167 + 201) / 3.Я пытался реализовать это, используя среднее, смещение, индекс, но я просто не знаю как.Я немного знаком с макросами, поэтому такое решение будет работать нормально: =MovingAverage(A1;3)

Спасибо за любые советы или решения!

Ответы [ 4 ]

7 голосов
/ 12 марта 2011
{=SUM(($A$1:A9)*(ROW($A$1:A9)>LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1)))/3}

Введите это с помощью control + shift + enter, чтобы сделать его формулой массива.Это найдет последние три значения.Если вы хотите больше или меньше, замените два экземпляра «3» в формуле на то, что вы хотите.

LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1)

Эта часть возвращает 4-й по величине номер строки из всех ячеек, имеющих значение, или5 в вашем примере, потому что строки 6, 8 и 9 являются 1-м по 3-й старшими строками со значением.

(ROW($A$1:A9)>LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1))

Эта часть возвращает 9 TRUE или FALSE в зависимости от того, является ли номер строки больше 4-гоСамый большой.

($A$1:A9)*(ROW($A$1:A9)>LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1))

Это умножает значения в A1: A9 на эти 9 ИСТИНА или ЛОЖЬ.ИСТИНА конвертируется в 1, а ЛОЖЬ - в ноль.Таким образом, функция SUM остается такой:

=SUM({0;0;0;0;0;155;0;167;201})/3

Поскольку все значения выше 155 не удовлетворяют критерию номера строки, значение get умножается на ноль.

3 голосов
/ 13 марта 2011

Если вы собираетесь использовать UDF, он будет корректно пересчитываться только при изменении данных, если параметры включают весь диапазон данных, которые вы хотите обработать.

Вот UDF со скользящей средней, который обрабатывает всестолбцы и содержит некоторые обработки ошибок.Вы можете вызвать это, введя формулу =MovingAverage(A:A,3) в ячейку.

Function MovingAverage(theRange As Range, LastN As Long) As Variant
    Dim vArr As Variant

    Dim j As Long
    Dim nFound As Long
    Dim dSum As Double

    On Error GoTo Fail
    MovingAverage = CVErr(xlErrNA)
    '
    ' handle entire column reference
    '
    vArr = Intersect(Application.Caller.Parent.UsedRange, theRange).Value2

    If IsArray(vArr) And LastN > 0 Then
        For j = UBound(vArr) To 1 Step -1
            ' skip empty/uncalculated
            If Not IsEmpty(vArr(j, 1)) Then
                ' look for valid numbers
                If IsNumeric(vArr(j, 1)) Then
                    If Len(Trim(CStr(vArr(j, 1)))) > 0 Then
                        nFound = nFound + 1
                        If nFound <= LastN Then
                            dSum = dSum + CDbl(vArr(j, 1))
                        Else
                            Exit For
                        End If
                    End If
                End If
            End If
        Next j

        If nFound >= LastN Then MovingAverage = dSum / LastN

    End If
    Exit Function
Fail:
    MovingAverage = CVErr(xlErrNA)
End Function
1 голос
/ 13 марта 2011

Я написал короткий сценарий на VBA.Надеюсь, он делает то, что вы хотите.Вот вы:

Function MovingAverage(ByVal r As String, ByVal i As Integer) As Double
Dim rng As Range, counter As Long, j As Integer, tmp As Double
    Set rng = Range(r)
    counter = 360
    j = 0
    tmp = 0
    While j < i + 1 And counter > 0
        If Len(rng.Offset(j, 0)) > 0 Then
            tmp = tmp + rng.Offset(j, 0).Value
        End If
        j = j + 1
        counter = counter - 1
    Wend
    MovingAverage = CDbl(tmp / i)
End Function

1) Я установил лимит в 360 ячеек.Это означает, что скрипт не будет искать больше 360 ячеек.Если вы хотите изменить его, измените начальное значение counter .

2) Скрипт возвращает не округленное среднее значение.Измените последнюю строку на MovingAverage = Round (CDbl (tmp / i), 2)

3) Использование такое, как вы хотели, поэтому просто введите = MovingAverage ("a1 "; 3) в клетку.

Любые комментарии приветствуются.

1 голос
/ 12 марта 2011

Просто быстрое решение: Предположим, что ваши цифры указаны в ячейках A2: A10, в B10 введите следующую формулу:

=IF(COUNT(A8:A10)=3,AVERAGE(A8:A10),IF(COUNT(A7:A10)=3,AVERAGE(A7:A10),"too many blanks"))

При перемещении по формуле вы получаете скользящее среднее

Если есть возможность двух последовательных пропусков, вы можете вкладывать другой, если, более того, и это решение стало слишком сложным

...