it-swarm.com.de

Wie berechnet man gewichtete Durchschnittswerte in Google Sheets?

Ich habe ein Google Sheets, in dem Produkte als Zeilen und Attribute als Spalten aufgeführt sind. Die Attribute jedes Produkts werden auf einer Skala von 1 bis 10 bewertet. Meine letzte Spalte ist ein Durchschnitt dieser Werte (d. H. =Average(B2:D2)). Dies funktioniert gut, wenn jedes Attribut das gleiche Gewicht hat.

+--------+-------+-------+-------+---------+
|        | Attr1 | Attr2 | Attr3 | Overall |
+--------+-------+-------+-------+---------+
| Prod 1 | 10    | 8     | 9     | 9       |
| Prod 2 | 2     | 10    | 7     | 6.33    |
| Prod 3 | 4     | 6     | 6     | 5.33    |
+--------+-------+-------+-------+---------+

Das Problem ist, dass jedes Attribut ein anderes Gewicht haben soll. Beispielsweise ist Attr1 möglicherweise nicht wichtig und sollte nur 50% wert sein, während Attr3 sehr wichtig ist und 300% wert sein sollte.

+--------+-------------+-------+--------------+---------+
|        | Attr1 (50%) | Attr2 | Attr3 (300%) | Overall |
+--------+-------------+-------+--------------+---------+
| Prod 1 | 10          | 8     | 9            | 8.89    |
| Prod 2 | 2           | 10    | 7            | 7.11    |
| Prod 3 | 4           | 6     | 6            | 5.78    |
+--------+-------------+-------+--------------+---------+

Der Wert für die erste Zeile wäre:

(10*0.5 + 8*1 + 9*3) / (0.5+1+3) = 8.89

das könnte berechnet werden mit:

(
  B2*(IFERROR(REGEXEXTRACT(B1, "\d+"), 100)/100) 
  + C2*(IFERROR(REGEXEXTRACT(C1, "\d+"), 100)/100)
  + D2*(IFERROR(REGEXEXTRACT(D1, "\d+"), 100)/100) 
) / (
  IFERROR(REGEXEXTRACT(B1, "\d+"), 100)/100
  + IFERROR(REGEXEXTRACT(C1, "\d+"), 100)/100
  + IFERROR(REGEXEXTRACT(D1, "\d+"), 100)/100
)

wie Sie sehen, kann die Verwaltung sehr schwierig werden, wenn weitere Attribute hinzugefügt werden. Idealerweise suche ich nach einer Lösung, bei der keine temporären Zellen für die Berechnungen erstellt werden müssen.

Gibt es eine eingebaute Funktion oder eine gemeinsame Konvention, mit deren Hilfe ich diese gewichteten Durchschnittswerte berechnen kann?

36
Senseful

Es gibt keine integrierte Funktion zum Berechnen des gewichteten Durchschnitts. Sie müssen daher eine benutzerdefinierte Funktion schreiben, um die Verwendung zu vieler temporärer Zellen zu vermeiden. So können Sie Ihr Ziel erreichen.

Gehen Sie zu Tools > Scripts > Skripteditor ... , Kopieren Sie den folgenden Code, fügen Sie ihn ein und speichern Sie ihn:

function weightedAverage(v, w) {
  var sum_v = 0;
  var sum_w = 0;

  if (v[0].length != w[0].length) {
    return "#ERROR: Incorrect number of values and weights";  
  }

  for (var c = 0; c < v[0].length; ++c) {
    sum_v += v[0][c] * w[0][c]; 
    sum_w += w[0][c]; 
  }

  return sum_v/sum_w;
}​

Verwenden Sie es wie folgt:

=weightedAverage(B3:D3,$B$2:$D$2) 

Wobei B3:D3 Ihre Werte und $B$2:$D$2 Ihre Gewichte sind. Es ist nicht fehlersicher (die einzige Überprüfung besteht darin, sicherzustellen, dass beide Arrays die gleiche Länge haben), aber es wird den Trick machen.

Im obigen Beispiel versuche ich nicht, die Gewichte aus dem Titel des Attributs zu extrahieren, sondern lese sie aus der zweiten Zeile (B2:D2), um unser Leben einfacher und klarer zu gestalten. Der $ ändert das Ergebnis der Formel nicht. Es wirkt sich nur auf das aus, was passiert, wenn Sie die Formel in eine andere Zelle kopieren. Der Teil der Zellreferenz, der auf $ folgt, ändert sich nicht ( link für weitere Details). Schreiben Sie die Formel einmal in die Zelle E3 und kopieren Sie sie in die restlichen Zeilen, um sie in Aktion zu sehen.

8
Lipis

Wenn sich Ihre Gewichte in Zeile 2 von B bis L befinden und die Daten, die Sie mitteln möchten, beispielsweise in Zeilen 3 und höher sind, können Sie sumproduct wie folgt verwenden:

=sumproduct(B$2:L$2, C3:L3)/sum(B$2:L$2)
58
Brendan Murphy

Google schien zugehört zu haben. Zumindest in meiner Instanz von Google Sheets ist die Funktion AVERAGE.WEIGHTED vorhanden. Per der Hilfe:

=AVERAGE.WEIGHTED(values,
                  weights,
                  [additional_values, ...],
                  [additional_weights, ...])
6
Tony Shouse

Der Code von Lipis hat bei mir nicht funktioniert, daher hier ein Update. Dieser Code:

  • funktioniert mit der aktuellen Version von Google Spreadsheets und adressiert Array-Elemente korrekt

  • prüft, ob die Werte Zahlen sind

  • hat einen Schalter, um Nullwerte zu berücksichtigen oder nicht

Code:

/**
  v - Values range
  w - Weights range
  z - count zero values?
*/

function weightedAverage(v, w, z) {
  var sum_v = 0;
  var sum_w = 0;

  if (v.length != w.length) {
    return "#ERROR: Incorrect number of values and weights";  
  }

  for (var c = 0; c < v.length; ++c) {
    if (!z && Number(v[c][0])!=0) {
      sum_v += Number(v[c][0]) * Number(w[c][0]); 
      sum_w += Number(w[c][0]); 
    }
  }

  return sum_v/sum_w;
}
2
Zhenya Morozov

Nachdem Sie Ihre Frage sorgfältig gelesen haben,

Idealerweise suche ich nach einer Lösung, bei der keine temporären Zellen für die Berechnungen erstellt werden müssen.

Ich habe diese Lösung gefunden, die keine temporären Zellen verwendet.

Formel

weights = ARRAYFORMULA(IFERROR(VALUE(REGEXEXTRACT($B$1:$D$1,"\((\d+)")),100))

=SUMPRODUCT(B3:D3, weights) / SUM(weights)

copy / paste
=SUMPRODUCT(B2:D2, ARRAYFORMULA(IFERROR(VALUE(REGEXEXTRACT($B$1:$D$1,"\((\d+)")),100)))/SUM(ARRAYFORMULA(IFERROR(VALUE(REGEXEXTRACT($B$1:$D$1,"\((\d+)")),100)))

Bildschirmfoto

enter image description here

Erklärt

REGEXEXTRACT extrahiert den Wert in der Kopfzeile nach der ersten geraden Klammer und VALUE konvertiert ihn in eine Zahl. IFERROR setzt den Wert auf 100, wenn nichts gefunden wird, und ARRAYFORMULA ermöglicht die Auswahl eines Bereichs anstelle einzelner Zellen.

Beispiel

Ich habe eine Beispieldatei für Sie erstellt: Wie werden gewichtete Durchschnittswerte in Google Spreadsheets berechnet?

0

Da die akzeptierte Antwort Google Apps Script verwendet, habe ich auch ein kleines Snippet erstellt.

Code

function weightedAverage(v, w) {
  var weights = [], sumWeights = 0;
  for(var k = 0, kLen = w[0].length; k < kLen; k++) {
    var m = w[0][k].match(/\((\d+)/), value;
    if(!m) {
      value = 100;
    } else {
      value = Number(m[1]);
    }
    weights.Push(value);
    sumWeights += value;
  }

  var output = [];
  for(var i = 0, iLen = v.length; i < iLen; i++) {
    var sumProduct = 0;
    for(var j = 0, jLen = v[0].length; j < jLen; j++) {
      sumProduct += v[i][j] * weights[j]; 
    }
    output.Push(sumProduct / sumWeights);
  } 
  return output;
}

Bildschirmfoto

enter image description here

Hinweis

Das Skript folgt der gleichen Logik wie in this post. Der Hauptvorteil ist, dass die Gesamtwerte sofort berechnet werden.

Beispiel

Ich habe eine Beispieldatei für Sie erstellt: Wie werden gewichtete Durchschnittswerte in Google Spreadsheets berechnet?

0

Korrektur des Lipis-Codes für die aktuelle Version von Google Spreadsheets:

function weightedAverage(v, w) {
  var sum_v = 0;
  var sum_w = 0;

  if (v.length != w.length) {
    return "#ERROR: Incorrect number of values and weights";  
  }

  for (var c = 0; c < v.length; ++c) {
    sum_v += v[c] * w[c]; 
    sum_w += w[c] * 1; 
  }

  return sum_v/sum_w;
}​
0
Sai

Für einfache gewichtete Durchschnitte können Sie den Zellenwert einfach mehrfach addieren. Wenn Sie möchten, dass A1 75% und B1 25% beträgt, können Sie =AVERAGE (A1,A1,A1,B1) eingeben. Speziell für Sie wäre es also =AVERAGE (B2,C2,C2,D1,D2,D2,D2,D2,D2,D2), das B2 als die Hälfte von C2 (50%) und D2 als 3x C2 (300%) wiegt.

Kompliziertere Sachen liegen über meiner Gehaltsstufe. :)

0
Jason

Tatsächlich ergeben beide Versionen Average.weighted und sumproduct das gleiche Ergebnis:

AVERAGE.WEIGHTED("Values","Weight")

SUMPRODUCT("Numbers","Weight")/sum("Weight")

Ich verwende also lieber die erste, da sie viel einfacher zu handhaben ist, aber ich weiß nicht, wie ich dieser Formel andere Gewichte hinzufügen kann.

Dies ist der Tooltipp, aber ich weiß nicht, wie ich nur Gewichte und keine zusätzlichen Werte hinzufügen soll

AVERAGE.WEIGHTED(values, weights, [additional_values, ...], [additional_weights, ...])
0
Joao Carpio

ARRAYFORMULA () kann ein gewichteter Durchschnitt in Google Spreadsheets (und mehr) berechnen.

Das separate Speichern der Gewichte in B2: D2 vereinfacht das Lesen der Formel. Das Berechnen des gewichteten Durchschnitts für E3 sieht dann ähnlich aus wie das obige SUMPRODUCT () (Kopieren/Einfügen für E4 & E5):

=ARRAYFORMULA(sum(B3:D3 * $B$2:$D$2)/sum($B$2:$D$2))

+--------+-------------+-------+-------------+---------+
|        | AttrA (50%) | AttrB | AttrC (300%)| Overall |
| Weight:|        50%  |  100% |        300% |         |
+--------+-------------+-------+-------------+---------+
| Prod 1 |       10    |  8    |       9     | 8.8889  |
| Prod 2 |        2    | 10    |       7     | 7.1111  |
| Prod 3 |        4    |  6    |       6     | 5.7778  |
+--------+-------------+-------+-------------+---------+

Die Verwendung von RegExExtract (), um die Gewichte von $ B $ 1 zu erhalten: $ D $ 1 ist eine einfache Änderung in der ARRAYFORMULA (). Ersetzen Sie den einfachen Bereich durch den komplexeren Ausdruck "iferror(regexextract($B$1:$D$1,"\d+"),100)/100" und die Formel für E3 wird (Kopieren/Einfügen für E4 & E5):

=ARRAYFORMULA(sum(B3:D3 * iferror(regexextract($B$1:$D$1,"\d+"),100)/100)/sum(iferror(regexextract($B$1:$D$1,"\d+"),100)/100))

N.B. Für diesen regulären Ausdruck sind Attributnamen ohne Zahlen erforderlich. Verwenden Sie also AttrA, AttrB und AttrC anstelle von Attr1, Attr2 und Attr3.

0
M.W.