user3066571
user3066571

Reputation: 1471

LINQ find average from CSV objects

I have a CSV with stock info in it (that I have a list of DailyValues objects called stockValues) that I need to pull from. It looks like this:

Date,Open,High,Low,Close,Volume,Adj Close
2012-11-01,77.60,78.12,77.37,78.05,186200,78.05
2012-10-31,76.96,77.75,76.96,77.47,290700,77.47  //and so on

Essentially, I need to find the average volume for each year in the CSV with LINQ. I can do it, but it's sloppy and only works for one year, so I'd have to copy the segment a bunch of times to do it for each year (it has years 1993-2012). Here's what I have:

List<DailyValues> values2012 = stockValues.TakeWhile(n => n.Date.Year == 2012).ToList();
List<decimal> sum2012 = (from s in values2012
                         select s.Volume).ToList();
decimal average2012 = 0;
foreach(decimal el in sum2012)
{        
    average2012 += el;
}
average2012 /= sum2012.Count();

average2012 = decimal.Round(average, 2);

Console.WriteLine("2012 Average: " + average2012);

So, again, this works fine, but I don't want to have to do this for each year. Does anyone know of a way to simplify my issue?

Upvotes: 0

Views: 253

Answers (2)

Max Brodin
Max Brodin

Reputation: 3938

Can you try something like:

 var groupedValues = stockValues.GroupBy(n => n.Date.Year)
                   .Select (g => new {
                       Average = g.Average(p => p.Volume), 
                       Year = g.Key
                    });

This will return average for each year, please see this fiddle

Upvotes: 3

Rapha&#235;l Althaus
Rapha&#235;l Althaus

Reputation: 60493

var groupedResults = stockValues.GroupBy(m => m.Date.Year)
                               .Select(g => new {
                                  year = g.Key,
                                  avg = g.Average(s => s.Volume)
                               });


foreach (var res in groupedResults)
   Console.WriteLine("{0} average : {1}", res.year, res.avg));

Upvotes: 2

Related Questions