Лучший способ использовать функции статистики Math.NET для свойств объектов в списке

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

Вопрос

Я пытаюсь найти лучший способ быстрого выполнения вычислений и хотел выяснить, какой подход люди обычно используют в такой ситуации.

У меня есть список объектов, у которых есть свойства, по которым я хочу вычислить среднее и стандартное отклонение..Я думал, используя этот Библиотека Math.NET, вероятно, будет проще/оптимизирована по производительности.

К сожалению, входными аргументами этих функций являются массивы.Является ли мое единственное решение написать собственную функцию для расчета средних значений и ЗППП?Могу ли я написать какой-нибудь метод расширения для списков, который использует лямбда-функции, например здесь?Или мне лучше написать функции, которые возвращают массивы свойств моего объекта, и использовать их с Math.NET.

Вероятно, ответ зависит от некоторых вещей, например, от размера списка?Предположим, в качестве аргумента, что в списке 50 элементов.Меня беспокоит чисто производительность.

Это было полезно?

Решение

ArrayStatistics действительно ожидает массивы, поскольку он оптимизирован для этого особого случая (вот почему он называется ArrayStatistics).Сходным образом, StreamingStatistics оптимизирован для потоковой передачи последовательностей IEnumerable без хранения данных в памяти.Общий класс, который работает со всеми типами входных данных, — это Statistics сорт.

Убедились ли вы, что простое использование LINQ и StreamingStatistics недостаточно быстро в вашем случае?Вычисление этой статистики для списка всего из 50 записей вообще едва поддается измерению, если только, скажем, вы не делаете это миллион раз в цикле.

Пример с Math.NET Numerics v3.0.0-alpha7, использование кортежей в списке для эмуляции ваших пользовательских типов:

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

Другие советы

Eagist Change, которое вы можете использовать, - это поставить LINQ , чтобы преобразовать List на Array

  List<SomeClass> list = ...

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

Тем не менее, если перфекция является вашей проблемой, вы бы предпочтете вычислить среднее и диверсию явно (напишите свою собственную функцию):

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top