0

5 万行を超えるデータセットがあります。最初の 50 の値の平均、次に 2 番目の 50 の値などを取得することにしました (50 の値グループの平均を持つデータセットの半分を取得するため)。

これが私のコードです:

var Rate = (from dr in ds.Tables[0].AsEnumerable()
                                    select new
                                    {
                                        rate = dr.Field<double>(columnName)
                                    }.rate).ToList();
                            if (Rate.Count > 50)
                            {
                                var avg = Rate.CheckRateValue();
                            }

そして、これが私の拡張メソッドのコードです:

public static IEnumerable<double> CheckRateValue(this IEnumerable<double> values)
{
    int i = 1;
    int j = 0;
    for (; i < values.Count(); )
    {
        yield return values.Skip(j * 2).Take(2).Average();
        i = i + 2;
        j++;
    }
}

問題 : 正常に動作しますが、遅いです。スピードアップする方法について何か提案はありますか?

4

6 に答える 6

2

反復をスキップして作成するため、 DataTable.Computeの使用が高速になる場合がありますList<dobule>

double average = (double)ds.Tables[0].Compute("avg(columnName)", "");

2番目のパラメーターはフィトラー式であるため、テーブル内のデータで許可されている場合は、このパラメーターを使用してスキップを実行できます。

于 2012-05-17T13:30:28.677 に答える
1

50のカウントでアイテムを取得して平均化し(最初の50を取得、平均化、次の50を取得、平均化など)、平均のリストを取得する場合は、MoreLinqを使用できます。バッチ

使用できます

  var result = list.Batch(50).Select(x=> x.Average());
于 2012-05-17T13:29:19.113 に答える
1
var yourList=yourList.Take(50).Aggregate((acc, cur) => acc + cur) / list.Count
于 2012-05-17T13:20:47.973 に答える
0

なぜそれは単純よりも速いのでしょうか:

var average = dat.AsEnumerable().Average(dr => (double)dr["ColumnName"]);

実際、これはおそらく、一度に 50 を取得するという余分な複雑さよりも高速であるはずです...

于 2012-05-17T13:25:33.697 に答える
0

row_number() を使用して解決しました。

declare @Skip int = 20
declare @Take int = 10

select SomeColumn
from (
   select SomeColumn,
          row_number() over(order by SomeColumnToOrderBy) as rn
   from YourTable
 ) T
where rn > @Skip and 
  rn <= @Skip + @Take
于 2012-06-02T09:45:06.140 に答える
0

for { 利回り戻り値.Skip(j * 2).Take(2).Average(); }

各ループ反復で最初から現在のページに移動します。これは n^2 になります。画家のシュレミエルも参照。

一度列挙する必要がありますvalues

于 2012-05-17T14:38:09.373 に答える