我正在试图找出快速执行计算的最佳方法,并希望找出人们在这种情况下通常会采取什么样的方法。
我有一个对象列表,其中包含我想要计算的均值和标准差的属性。我认为使用this Math.NET库可能更容易/优化性能。
不幸的是,这些函数的输入参数是数组。我唯一的解决方案是编写自己的函数来计算均值和STD吗?我可以为使用像here这样的lambda函数的列表编写某种扩展方法吗?或者我最好编写返回我的对象属性数组的函数,并将它们与Math.NET一起使用。
据推测,答案取决于某些事情,比如列表的大小?让我们说为了论证,该列表有50个元素。我的担忧纯粹是表现。
答案 0 :(得分:5)
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));
答案 1 :(得分:1)
您可以使用的最简单的解决方案是放置 Linq ,以便将List
转换为数组
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);