リスト内のオブジェクトのプロパティでMath.net統計機能を使用するための最良の方法
-
21-12-2019 - |
質問
私は計算を速く実行するための最良の方法を見つけようとしていて、通常このような状況をどのような状況でどのような方法でどのようなものであるかを見つけたいと思っています。
残念ながら、これらの機能の入力引数は配列です。私の唯一の解決策は、平均とstdsを計算するための私自身の関数を書くのですか? こちら?または、オブジェクトのプロパティの配列を返し、Math.netを使用してこれらを使用する機能を書くことをお勧めします。
おそらく答えはリストのサイズのようなものによって異なりますか?リストに50の要素があるという議論のために言ってみましょう。私の懸念は純粋に性能です。
解決
ArrayStatistics
は、この特別な場合に最適化されているため、配列を期待しています(それがArrayStatisticsと呼ばれる理由です)。同様に、StreamingStatistics
は、データをメモリに保持することなく、IEnumerableシーケンスストリーミングのために最適化されています。すべての種類の入力で機能する一般クラスはStatistics
クラスです。
単にLINQとStreamingStatisticsを使用することはあなたのユースケースで十分に速くないことを確認しましたか?単に50のエントリのリストのためのこれらの統計を計算することは、ループ内の100万回の時間を実行しない限り、まったく測定できません。
Math.net数値数値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));
. 他のヒント
使用できる最も熱心な解決策は、 linq を変換することで、 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);
.