Il modo migliore per utilizzare le funzioni di statistiche math.net sulle proprietà degli oggetti in un elenco

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

Domanda

Sto cercando di capire il modo migliore per eseguire un calcolo velocemente e volevo scoprire che tipo di approccio le persone di solito assumono una situazione come questa.

Ho un elenco di oggetti che hanno proprietà che voglio calcolare la deviazione media e standard di . Pensavo di usare Questa libreria math.net sarebbe probabilmente più facile / ottimizzato per le prestazioni.

Sfortunatamente, gli argomenti di input per queste funzioni sono array. La mia unica soluzione è scrivere la mia funzione per calcolare i mezzi e le STD? Potrei scrivere una sorta di metodo di estensione per gli elenchi che utilizza le funzioni Lambda come qui ? Oppure sto meglio di scrivere funzioni che restituiscono gli array delle proprietà dell'oggetto e usano questi con math.net.

Presumibilmente la risposta dipende da alcune cose come le dimensioni della lista? Diciamo per l'argomento che la lista ha 50 elementi. La mia preoccupazione è puramente prestazioni.

È stato utile?

Soluzione

ArrayStatistics Aspetta effettivamente gli array in quanto è ottimizzato per questo caso speciale (è per questo che è chiamato Arraystatistics).Allo stesso modo, StreamingStatistics è ottimizzato per lo streaming di sequenza di Ienumarableless senza mantenere i dati in memoria.La classe generale che funziona con tutti i tipi di input è la classe Statistics.

Hai verificato che semplicemente usare LINQ e StreamingStatistics non è abbastanza veloce nel tuo caso di utilizzo?In calcolo di queste statistiche per un elenco di puramente 50 voci è a malapena misurabile, a meno che, a meno che non lo fai un milione di volte in un loop.

Esempio con Math.net Numerics V3.0.0-Alpha7, utilizzando Tuples in un elenco per emulare i tipi personalizzati:

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

Altri suggerimenti

La soluzione più capatica che è possibile utilizzare è mettere linq in modo da trasformare List su array

  List<SomeClass> list = ...

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

Tuttavia, se la performance è la tua preoccupazione, preferiresti calcolare esplicitamente la media e la varianza (scrivi la tua funzione):

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top