La mejor manera de utilizar las funciones estadísticas de Math.NET en las propiedades de los objetos en una Lista

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

Pregunta

Estoy tratando de descubrir la mejor manera de realizar un cálculo rápidamente y quería saber qué tipo de enfoque adoptaría normalmente la gente en una situación como esta.

Tengo una lista de objetos que tienen propiedades de las que quiero calcular la media y la desviación estándar..Pensé en usar este La biblioteca Math.NET probablemente sería más fácil/optimizada para el rendimiento.

Desafortunadamente, los argumentos de entrada para estas funciones son matrices.¿Mi única solución es escribir mi propia función para calcular medias y ETS?¿Podría escribir algún tipo de método de extensión para listas que use funciones lambda como aquí?¿O sería mejor escribir funciones que devuelvan matrices de las propiedades de mi objeto y usarlas con Math.NET?

¿Presumiblemente la respuesta depende de algunas cosas como el tamaño de la lista?Digamos, a modo de argumento, que la lista tiene 50 elementos.Mi preocupación es puramente el rendimiento.

¿Fue útil?

Solución

ArrayStatistics de hecho espera matrices ya que está optimizada para este caso especial (por eso se llama ArrayStatistics).Similarmente, StreamingStatistics está optimizado para la transmisión de secuencias IEnumerable sin mantener datos en la memoria.La clase general que funciona con todo tipo de entrada es la Statistics clase.

¿Ha verificado que simplemente usar LINQ y StreamingStatistics no es lo suficientemente rápido en su caso de uso?Calcular estas estadísticas para una lista de apenas 50 entradas apenas se puede medir, a menos que lo hagas un millón de veces seguidas.

Ejemplo con Math.NET Numerics v3.0.0-alpha7, usando tuplas en una lista para emular sus tipos personalizados:

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

Otros consejos

La solución más temerente que puede usar es poner linq para que transforme List a matriz

  List<SomeClass> list = ...

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

Sin embargo, si la perforación es su preocupación, preferiría que compute la media y la varianza explícitamente (escriba su propia función):

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top