Question

I have a input stream where the input element consist of Date, Depth and Area. I want to plot the Area against the Depth and want therefor to take out a window of Depth e.g. between 1.0-100.0m. The problem is that I want to down sample the input stream since there can be many inputs with close Depth values. I want to partition the input into x bins, e.g. 2 bins means all depth values between 1-50 is averaged in the first bin and 51-100 in the second bin.

I was thinking something like this:

var q = from e in input
         where (e.Depth > 1) && (e.Depth <= 100)
         // here I need some way of partition the sequence into bins
         // and averaging the elements.

Split a collection into `n` parts with LINQ? wants to do something similar without rx.

Was it helpful?

Solution

Modified answer as per your comment. steps = number of buckets.

var min = 1, max = 100;
var steps = 10;
var f = (max - min + 1) / steps; // The extra 1 is really an epsilon. #hack
var q = from e in input
        where e.Depth > 1 && e.depth <= 100
        let x = e.Depth - min
        group e by x < max ? (x - (x % f)) : ;

This is the function we're grouping by for the given e.Depth.

enter image description here

This probably won't work so great with floating point values (due to precision), unless you floor/ceil the selection, but then you might run out of integers, so you may need to scale a bit... something like group e by Math.Floor((x - (x % f)) * scaleFactor).

OTHER TIPS

This should do what you want

static int GetBucket(double value, double min, double max, int bucketCount)
{
    return (int)((value - min) / (max - min) * bucketCount + 0.5);
}

var grouped = input.GroupBy(e => GetBucket(e.Depth, 1, 100, 50));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top