2016-03-09 6 views
0

Я ищу способ элегантно усреднить в 2D-массиве. У меня есть код, который работает для небольшого диапазона элементов, но мне нужно что-то, что я могу использовать для большого количества элементов.среднее значение в массиве

Вот код, который у меня есть для небольшого количества элементов. Этот код будет содержать три элемента в одной строке и возвращает ответ на массив результатов. Как я могу переписать это, если 50 элементов? Как вы можете себе представить, такой подход не будет работать хорошо для большого количества элементов.

For i = 1 To UBound(TMP) 
       results(i, 1) = ((TMP(i, 13) + TMP(i, 14) + TMP(i, 15))/3) 
    Next i 

ответ

0

Вы переместили бы нужные значения в 1D-массив, а затем применили бы функцию application.Average(). Например:

Dim rwarr() As Double 

For i = 1 To UBound(TMP, 1) 
    ReDim rwarr(1 To UBound(TMP, 2)) As Double 
    For j = 1 To UBound(TMP, 2) 
     rwarr(j) = TMP(i, j) 
    Next j 
    results(i, 1) = Application.Average(rwarr) 
Next i 
0

Вот функция, которая может принимать среднее количество столбцов в каждой строке 2-мерного массива.

Public Function AverageRowsIn2DArray(Arr As Variant, LBoundCol As Integer, UBoundCol As Integer) As Variant 
    Dim iNumValues As Integer 
    iNumValues = UBoundCol - LBoundCol + 1 
    If iNumValues < 1 Then GoTo ErrHandler 
    On Error GoTo ErrHandler 
    Dim retArr As Variant 
    Dim inArr As Variant 
    If TypeName(Arr) = "Range" Then 
     inArr = Arr.Value 
    Else 
     inArr = Arr 
    End If 

    ReDim retArr(1 To UBound(inArr), 1 To 1) 

    Dim i As Integer, j As Integer 
    Dim dSum As Double 

    For i = 1 To UBound(inArr) 
     dSum = 0 
     For j = LBoundCol To UBoundCol 
      dSum = dSum + inArr(i, j) 
     Next j 
     retArr(i, 1) = dSum/iNumValues 
    Next i 

    AverageRowsIn2DArray = retArr 
    Exit Function 

ErrHandler: 
    AverageRowsIn2DArray = 0 
End Function 

В вашем конкретном случае, вы хотите позвонить

Dim results() as Double 
results = AverageRowsIn2DArray(TMP, 13, 15) 
+0

Спасибо за помощь Скотт! – centurion79b

0

Спасибо за функции Скотт. Я немного изменил его, чтобы ограничить ввод одной строкой. Он отлично работает! Спасибо. Вот модифицированная функция:

Public Function AverageRowsIn2DArray(Arr As Variant, Nrow As Integer, LBoundCol As Integer, UBoundCol As Integer) As Variant 
    Dim iNumValues As Integer 
    iNumValues = UBoundCol - LBoundCol + 1 
    If iNumValues < 1 Then GoTo ErrHandler 
    On Error GoTo ErrHandler 
    Dim retArr As Integer 
    Dim inArr As Variant 
    If TypeName(Arr) = "Range" Then 
     inArr = Arr.Value 
    Else 
     inArr = Arr 
    End If 

    Dim i As Integer, j As Integer 
    Dim dSum As Double 


    For i = LBoundCol To UBoundCol 
     dSum = dSum + inArr(Nrow, i) 
    Next i 
    retArr = dSum/iNumValues 


    AverageRowsIn2DArray = retArr 
    Erase inArr 
    retArr = 0 
    Exit Function 

ErrHandler: 
    AverageRowsIn2DArray = 0 
End Function 

теперь мой вызов,

results(i, 4) = AverageRowsIn2DArray(TMP, i, 13, 15) 
0

Если предположить, что у вас меньше, чем 30К элементов первого ранга, используйте WorksheetFunction objectINDEX function шелушиться строку для обработки AVERAGE из.

Sub avgVals() 
    Dim tmp As Variant, results As Variant, a As Long 

    With Worksheets("Sheet2") 
     With .Cells(1, 1).CurrentRegion 
      With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0) 
       tmp = .Cells.Value2 
      End With 

      ReDim results(LBound(tmp, 1) To UBound(tmp, 1), 1 To 1) 
      For a = LBound(tmp, 1) To UBound(tmp, 1) 
       results(a, 1) = Application.Average(Application.Index(tmp, a, 0)) 
      Next a 

      With .Resize(.Rows.Count - 1, 1).Offset(1, .Columns.Count) 
       .Cells.Resize(UBound(results, 1), UBound(results, 2)) = results 
      End With 

     End With 


    End With 
End Sub 

Использование Excel Application object для облегчения INDEX нарезки массив врозь не самый быстрый метода и в конечном счете, он имеет limiations, но он может обеспечить целесообразный метод достижения ваших AVERAGE результатов для небольших партий.

Смежные вопросы