我有一个表达式:
Records.OrderBy(o => o.TIME).Where((o, i) => i % interval == 0).ToList();
这可以很好地获取大量数据记录并将其削减到较小的列表。 (interval是要跳过的记录数)。问题是,我想平均一些字段,而不是跳过它们。我不知道如何在不进行大循环的情况下做到这一点。值得注意的是,每个数据记录大约有90个字段。想法?
编辑:我希望能够完全跳过每个第n条记录,并平均2个特定字段(lat和long(存储为十进制)),并且很可能不会触及其他88个字段。
编辑:我想从
开始 timelat longmany other fields
1 2 3 field1
2 3 4 field1
3 4 5 field1
4 5 6 field1
5 6 7 field1
6 7 8 field1
7 8 9 field1
8 9 10 field1
9 10 11 field1
10 11 12 field1
11 12 13 field1
12 13 14 field1
致:
timelat long other fields
3 3 4 field1
6 6 7 field1
9 9 10 field1
12 12 13 field1
答案 0 :(得分:2)
如果要平均包含给定记录,则必须触摸该记录。 Something 将不得不循环遍历所有记录,无论您是明确地执行此操作还是Linq是否在幕后执行此操作。
给定的Linq表达式只能返回一个东西。
您当前拥有的Linq表达式将返回已过滤的列表。
您需要第二个Linq表达式(或您自己的循环)来平均所有记录,例如
var avg = Records.Average(r => r.FieldToAverage);
我不确定你的意思
值得注意的是,每个数据记录大约有90个字段
您是否必须在给定记录中平均字段?如果是这样,它们是什么数据类型?是否有一些现有的方法来枚举所有这些字段?如果没有,您将需要显式访问每个字段,或使用反射来枚举(相关)字段。
答案 1 :(得分:2)
您应该能够将其粘贴在Where子句中。它会有点难看但是这样的东西:
[编辑:从你的编辑我现在明白你想要的东西有点不同。此代码已相应编辑]。
decimal latSum = 0;
decimal longSum = 0;
int count = 0;
var recordList = Records
.OrderBy(o => o.TIME)
.Where((o, i) => {
if (i % interval == 0)
{
// Modify the record in place (hope that's OK)
o.Lat = (o.Lat + latSum) / (count + 1);
o.Long = (o.Long + longSum) / (count + 1);
latSum = longSum = count = 0;
return true;
}
latSum += o.Lat;
longSum += o.Long;
count++;
return false;
})
.ToList();
答案 2 :(得分:2)
如果我理解正确,您希望将大量项目分组到较小数量的同等大小的“桶”中,其中对于每个桶,一些字段被聚合(例如,平均)并且一些字段被跳过(即取自桶中的最后一项)。
考虑一下你是否可以这样做:
Records
.ToBuckets(interval)
.Select(bucket => new Record {
Time = bucket.Last().Time,
Count = bucket.Count,
Lat = bucket.Average(x => x.Lat),
Long = bucket.Average(x => x.Long),
Other = bucket.First().Other
}
.ToList()
如果这是你想要的,你需要做的就是创建ToBuckets方法,这是一个更简单(和通用!)的问题:
public static IEnumerable<IList<T>> ToBuckets(this IEnumerable<T> source, int size)
{
var bucket = new List<T>(size);
foreach (var item in source)
{
bucket.Add(item);
if (bucket.Count == size) {
yield return bucket;
bucket = new List<T>(size); // or you can use the same one if you're careful
}
if (bucket.Count > 0) yield return bucket;
}
(以上是作为支持该示例的扩展方法,但当然这也可以是常规方法。)