0

我有一个包含超过 50k 行的数据集。我决定取前 50 个值的平均值,然后取后 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)", "");

第二个参数是一个 fitler 表达式,因此如果表中的数据允许,您可以使用它来进行跳过。

于 2012-05-17T13:30:28.677 回答
1
var yourList=yourList.Take(50).Aggregate((acc, cur) => acc + cur) / list.Count
于 2012-05-17T13:20:47.973 回答
1

如果你想取 50 个项目并取平均值(比如取前 50 个,取平均值,取接下来的 50 个,取平均值,等等),并获取平均值列表,你可以使用MoreLinq

您可以使用

  var result = list.Batch(50).Select(x=> x.Average());
于 2012-05-17T13:29:19.113 回答
0

为什么这会比简单的更快:

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

事实上 - 这应该比一次取 50 个的额外复杂性更快......

于 2012-05-17T13:25:33.697 回答
0

for { 产生返回值.Skip(j * 2).Take(2).Average(); }

在每次循环迭代中从开始移动到当前页面:这将是 n^2。另见画家施莱米尔

你应该枚举values一次!

于 2012-05-17T14:38:09.373 回答
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 回答