Meilleure façon d'utiliser les fonctions statistiques Math.NET sur les propriétés des objets dans une liste

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

Question

J'essaie de trouver la meilleure façon d'effectuer un calcul rapidement et je voulais savoir quel type d'approche les gens adopteraient habituellement dans une situation comme celle-ci.

J'ai une liste d'objets qui ont des propriétés dont je souhaite calculer la moyenne et l'écart type..Je pensais utiliser ce La bibliothèque Math.NET serait probablement plus simple/optimisée pour les performances.

Malheureusement, les arguments d'entrée de ces fonctions sont des tableaux.Ma seule solution est-elle d'écrire ma propre fonction pour calculer les moyennes et les MST ?Puis-je écrire une sorte de méthode d'extension pour les listes qui utilise des fonctions lambda comme ici?Ou est-ce que je ferais mieux d'écrire des fonctions qui renvoient des tableaux de mes propriétés d'objet et de les utiliser avec Math.NET.

Vraisemblablement, la réponse dépend de certains éléments comme la taille de la liste ?Disons, à titre indicatif, que la liste comporte 50 éléments.Mon souci est purement la performance.

Était-ce utile?

La solution

ArrayStatistics attend en effet des tableaux car il est optimisé pour ce cas particulier (c'est pourquoi il s'appelle ArrayStatistics).De la même manière, StreamingStatistics est optimisé pour le streaming de séquences IEnumerable sans conserver les données en mémoire.La classe générale qui fonctionne avec tout type d'entrée est la Statistics classe.

Avez-vous vérifié que la simple utilisation de LINQ et StreamingStatistics n'est pas assez rapide dans votre cas d'utilisation ?Calculer ces statistiques pour une liste de seulement 50 entrées est à peine mesurable, à moins de le faire un million de fois en boucle.

Exemple avec Math.NET Numerics v3.0.0-alpha7, utilisant des tuples dans une liste pour émuler vos types personnalisés :

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));

Autres conseils

La solution la plus simple que vous puissiez utiliser est de mettre Linq pour que se transforme List à tableau

  List<SomeClass> list = ...

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

Cependant, si la performance vous préoccupe, vous préférez calculer explicitement la moyenne et la variance (écrivez votre propre fonction) :

  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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top