6

複数の列を含むデータテーブルがあります。グループ化せずにlinqでこれらの平均を計算したい:私はこれを試した:

dtPointCollFb.GroupBy(r => 1).Select(r => new
        {
            Plus100 = r.Average(item => item.PLUS100),
            Plus50 = r.Average(item => item.PLUS50),
            Plus10 = r.Average(item => item.PLUS10),
            Plus5 = r.Average(item => item.PLUS5),
            Plus1 = r.Average(item => item.PLUS1),
            NULLA = r.Average(item => item.NULLA)
        }).ToList()

合計を計算すると、これは完全に機能しますが、平均を使用すると、すべてのレコードの平均ではなく、最初のレコードの値が生成されます。これは不要だと思います: .GroupBy(r => 1) 定数でグループ化しているためです。

しかし、これがなければ、クエリ全体と1つの列だけに平均を使用することはできません:

dtPointCollFb.Average(r => r.PLUS100)

では、誰かが簡単なベスト プラクティス ソリューションを作成できますか? クエリではなく、メソッド構文で可能であれば。

私はこのようなものが欲しい:

dtPointCollFb.GroupBy(r => 0).Select(r => new
        {
            Plus100 = r.Sum(item => item.PLUS100) / dtPointCollFb.Rows.Count,
            Plus50 = r.Sum(item => item.PLUS50) / dtPointCollFb.Rows.Count,
            Plus10 = r.Sum(item => item.PLUS10) / dtPointCollFb.Rows.Count,
            Plus5 = r.Sum(item => item.PLUS5) / dtPointCollFb.Rows.Count,
            Plus1 = r.Sum(item => item.PLUS1) / dtPointCollFb.Rows.Count,
            NULLA = r.Sum(item => item.NULLA) / dtPointCollFb.Rows.Count
        }).ToList()

しかし、よりシンプルでクリーンな方法で。これにより、平均が正しく生成されます。

4

2 に答える 2

3

クリストファーが提案したように、拡張機能を使用したい場合は、Aggregateメソッドを使用できます。

クラスを考えると

public class DataPoint
{
    public double Plus100 { get; set; }
    public double Plus50 { get; set; }
    public double Plus10 { get; set; }
    public double Plus5 { get; set; }
    public double Plus1 { get; set; }
    public double NULLA { get; set; }
}

平均化関数は次のようになります (手動カウントにより、コレクション全体で複数の列挙が回避されます)。

public static DataPoint Average(this IEnumerable<DataPoint> dataPoints)
{
    var count = 0;
    var totals = dataPoints.Aggregate((lhs, rhs) =>
        {
            ++count;
            return new DataPoint
                {
                    Plus100 = lhs.Plus100 + rhs.Plus100,
                    Plus50 = lhs.Plus50 + rhs.Plus50,
                    Plus10 = lhs.Plus10 + rhs.Plus10,
                    Plus5 = lhs.Plus5 + rhs.Plus5,
                    Plus1 = lhs.Plus1 + rhs.Plus1,
                    NULLA = lhs.NULLA + rhs.NULLA
                };
        });

    return new DataPoint
        {
            Plus100 = totals.Plus100 / count,
            Plus50 = totals.Plus50 / count,
            Plus10 = totals.Plus10 / count,
            Plus5 = totals.Plus5 / count,
            Plus1 = totals.Plus1 / count,
            NULLA = totals.NULLA / count
        };
}

この方法の利点は、コレクションを一度だけ通過することです。大規模なデータセットがある場合、これにより計算能力が節約されます。データポイントが少ない場合は、クリストファーの方法を使用します。

于 2013-06-07T10:06:12.913 に答える