DevJoe
DevJoe

Reputation: 419

Create intervals of data with LINQ

I have an issue in C# that I can't figure out how to solve:

I have a set of data that consist of a TimeStamp and a value. This is a sample dataset:

<Timestamp>2014-01-06T17:40:08.000Z</TimeStamp>
<Value>200</Value>
<Timestamp>2014-01-06T17:40:09.000Z</TimeStamp>
<Value>234</Value>
<Timestamp>2014-01-06T17:40:11.000Z</TimeStamp>
<Value>214</Value>
<Timestamp>2014-01-06T17:40:12.000Z</TimeStamp>
<Value>264</Value>
<Timestamp>2014-01-06T17:40:13.000Z</TimeStamp>
<Value>300</Value>
<Timestamp>2014-01-06T17:40:15.000Z</TimeStamp>
<Value>276</Value>

What I need to do is to somehow get the average of the values by every 30 seconds. Notice that the recordings of data is not necessarily every second. This is what makes it hard for me to imagine how to do this without having an insecurity in the results.

Is this achievable through a LINQ statement or do you have other suggestions?

Upvotes: 2

Views: 1159

Answers (2)

Kobi
Kobi

Reputation: 138007

Assuming you can figure out how to parse the XML, and you have a collection of objects with Time and Value. For example, I'll use this collection:

var now = DateTime.Now;
var random = new Random();
var times = Enumerable.Range(1, 10000).Select(i => new
{
    Time = now.AddHours(random .NextDouble()),
    Value = i
});

Using a helper method DateTime RoundUp(DateTime dt, TimeSpan d), and GroupBy:

var interval = TimeSpan.FromSeconds(30);
var intervalAverageValues =
    times.GroupBy(t => RoundUp(t.Time, interval))
         .Select(g => new
         {
             AverageValue = g.Average(t => t.Value),
             IntervalEndTime = g.Key,
             Count = g.Count()
         });

Upvotes: 2

Alex
Alex

Reputation: 1109

Consider this pseudo answer :)

  1. Take your list of values and their timestamps and produce a list of Tuple<int, int>{} this is assuming your values are ints. Where first int is index and second int is the value;
  2. As you are filling the tuples list you need to take the total seconds component of your timestamp and divide it by 30. The result should be rounded to closest int.
  3. At this point you have a list of tuples that has values paired with their corresponding '30 second' group index;
  4. Use a simple group linq to produce your averages. Basically you loop over your groups and sum the values. Then divide by group's item count;

This is brute force approach somewhat. I'm sure there are smarter ways to do this.

Upvotes: 0

Related Questions