[英]How I can do this using skip and take in linq
I have a dataset which contains more than 50k rows. 我有一个包含超过5万行的数据集。 I decided to take average of the first fifty values, then second fifty values and so on (so that I will get half of the Dataset with average of 50 value groups). 我决定取前50个值的平均值,再取后50个值的平均值,依此类推(这样我将获得50个值组平均值的数据集的一半)。
Here is my code: 这是我的代码:
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();
}
And here is the code for my extension method: 这是我的扩展方法的代码:
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++;
}
}
Problem : It works fine but it's slow. 问题:可以正常运行,但是速度很慢。 Does anyone have any suggestions on how to speed it up? 有人对如何加快速度有任何建议吗?
Using the DataTable.Compute may be faster because you skip the iteration to create List<dobule>
. 使用DataTable.Compute可能会更快,因为您跳过了创建List<dobule>
的迭代。
double average = (double)ds.Tables[0].Compute("avg(columnName)", "");
The second parameter is a fitler expression so you could use it to do your skipping if the data in the table allows it. 第二个参数是fitler表达式,因此如果表中的数据允许,则可以使用它来跳过。
var yourList=yourList.Take(50).Aggregate((acc, cur) => acc + cur) / list.Count
If you want to take items in count of fifty and average it (like take first 50 , average it, take next 50, average it, and so on), and get list of Averages, you can use MoreLinq . 如果您要获取数量为50的项目并将其平均(例如,前50个,平均,下一个50,平均等),并获取平均列表,则可以使用MoreLinq 。 Batch 批量
You can use 您可以使用
var result = list.Batch(50).Select(x=> x.Average());
Why would that be any faster than simply: 为什么会比简单地更快呢?
var average = dat.AsEnumerable().Average(dr => (double)dr["ColumnName"]);
In fact - this should probably be faster than the extra complexity of taking 50 at a time... 实际上-这可能比一次服用50次额外的复杂性要快...
for { yield return values.Skip(j * 2).Take(2).Average(); 对于{收益率返回值。Skip(j * 2).Take(2).Average(); } }
Moving to the current page from the start in each loop iteration: that will be n^2. 在每个循环迭代中从头开始移至当前页面:那将是n ^ 2。 See also Schlemiel the painter . 另请参阅画家Schlemiel 。
You should enumerate values
once! 您应该一次枚举values
!
By using row_number() i solved it. 通过使用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.