Die beste Möglichkeit, Math.NET-Statistikfunktionen für die Eigenschaften von Objekten in einer Liste zu verwenden

StackOverflow https://stackoverflow.com//questions/22012737

Frage

Ich versuche herauszufinden, wie man eine Berechnung am besten schnell durchführen kann, und wollte herausfinden, welche Vorgehensweise die Leute normalerweise in einer solchen Situation wählen würden.

Ich habe eine Liste von Objekten mit Eigenschaften, deren Mittelwert und Standardabweichung ich berechnen möchte.Ich dachte mit Das Die Math.NET-Bibliothek wäre wahrscheinlich einfacher/leistungsoptimierter.

Leider sind die Eingabeargumente für diese Funktionen Arrays.Ist meine einzige Lösung, meine eigene Funktion zu schreiben, um Mittelwerte und STDs zu berechnen?Könnte ich eine Art Erweiterungsmethode für Listen schreiben, die Lambda-Funktionen wie verwendet Hier?Oder schreibe ich besser Funktionen, die Arrays meiner Objekteigenschaften zurückgeben und diese mit Math.NET verwenden?

Vermutlich hängt die Antwort von einigen Dingen ab, wie zum Beispiel der Größe der Liste?Nehmen wir zur Argumentation an, dass die Liste 50 Elemente enthält.Mir geht es rein um die Leistung.

War es hilfreich?

Lösung

ArrayStatistics erwartet tatsächlich Arrays, da es für diesen Sonderfall optimiert ist (deshalb heißt es ArrayStatistics).Ähnlich, StreamingStatistics ist für IEnumerable-Sequenz-Streaming optimiert, ohne dass Daten im Speicher verbleiben.Die allgemeine Klasse, die mit allen Arten von Eingaben funktioniert, ist die Statistics Klasse.

Haben Sie überprüft, dass die einfache Verwendung von LINQ und StreamingStatistics in Ihrem Anwendungsfall nicht schnell genug ist?Die Berechnung dieser Statistiken für eine Liste mit lediglich 50 Einträgen ist kaum messbar, es sei denn, Sie führen dies eine Million Mal in einer Schleife durch.

Beispiel mit Math.NET Numerics v3.0.0-alpha7, bei dem Tupel in einer Liste verwendet werden, um Ihre benutzerdefinierten Typen zu emulieren:

using MathNet.Numerics.Statistics;

var data = new List<Tuple<string, double>>
{
    Tuple.Create("A", 1.0),
    Tuple.Create("B", 2.0),
    Tuple.Create("C", 1.5)
};

// using the normal extension methods within `Statistics`
var stdDev1 = data.Select(x => x.Item2).StandardDeviation();
var mean1 = data.Select(x => x.Item2).Mean();

// single pass variant (unfortunately there's no single pass MeanStdDev yet):
var meanVar2 = data.Select(x => x.Item2).MeanVariance();
var mean2 = meanVar2.Item1;
var stdDev2 = Math.Sqrt(meanVar2.Item2);

// directly using the `StreamingStatistics` class:
StreamingStatistics.MeanVariance(data.Select(x => x.Item2));

Andere Tipps

Die einfachste Lösung, die Sie verwenden können, ist put Linq also diese Transformation List Zu Array

  List<SomeClass> list = ...

  GetMeanAndStdError(list.ToArray()); // <- Not that good performance

Wenn Ihnen jedoch die Leistung am Herzen liegt, berechnen Sie Mittelwert und Varianz lieber explizit (schreiben Sie Ihre eigene Funktion):

  List<SomeClass> list = ...

  Double sumX = 0.0;
  Double sumXX = 0.0;

  foreach (var item in list) {
    Double x = item.SomeProperty;

    sumX += x;
    sumXX += x * x;
  }

  Double mean = sumX / list.Count;
  Double variance = (sumXX / list.Count - mean);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top