我有下面的列表,其中有一个具有两个属性的对象,Date和energy value,我必须计算每个月的平均能量。
我需要遵循的步骤是在所有这些中找到开始日期和结束日期,并找到年数,然后,每个月都需要计算平均能量。如果我看到多个月,我需要平均能量值。
public class DateEnergyValue
{
public DateOnly CollectedDate{ get; set; }
public double Value { get; set; }
}
List<DateEnergyValue> DateEnergyValues = new List<DateEnergyValue>() { .....}
我可以得到开始日期和结束日期如下。
var startDate = DateEnergyValues.Min(a => a.CollectedDate);
var endDate = DateEnergyValues.Max(r=>r.CollectedDate);
我也可以得到年数。
TimeSpan TS = startDate - endDate;
double Years = TS.TotalDays / 365.25;
但不确定如何进行剩余的计算,以及下面的样本数据图像
采集日期(月/日/年) | 值 |
---|---|
2009年5月1日 | 2400 |
2009年6月1日 | 2400 |
2009年7月1日 | 2400 |
2009年8月1日 | 7315.8 |
2009年1月12日 | 369.7 |
2010年1月1日 | 369.7 |
2010年1月 | 144.8 |
2010年3月1日 | 437.2 |
2010年4月1日 | 804.1 |
2010年5月1日 | 965.1 |
2010年6月1日 | 1131 |
2010年7月1日 | |
2010年8月1日 | 1170.8|
2010年9月1日 | 993.6 |
2010年1月10日 | 714.9 |
2010年1月11日 | 244.3 |
2010年1月12日 | 126.8 |
2011年3月1日 | <185.2>|
2011年4月1日 | 441.9 |
2011年7月1日 | 3051.3 |
2011年9月1日 | 996 |
2011年1月10日 | 3328.7 |
2011年1月11日 | 870.1 |
2011年1月12日 | <1051.8>|
2011年4月1日 | 481000 |
2011年5月1日 | 446000 |
2011年6月1日 | 608000 |
2011年7月1日 | 33000 |
2011年8月1日 | 478000 |
9/1/2011 | |
2011年1月10日 | 505000 |
2011年1月11日 | 438000 |
计算最小和最大日期后,您可以迭代这两个日期之间的月份,并获得每个日期的平均值(如果没有找到该月份的匹配项,则为零):
static void Main(string[] args)
{
// the supplied data as a pipe and comma delimited string
String data =
"5/1/2009|2400,6/1/2009|2400,7/1/2009|2400,8/1/2009|7315.8,9/1/2009|5140.3," +
"10/1/2009|1557.8,11/1/2009|1557.8,12/1/2009|369.7,1/1/2010|369.7," +
"2/1/2010|144.8,3/1/2010|437.2,4/1/2010|804.1,5/1/2010|965.1,6/1/2010|1131," +
"7/1/2010|1179.4,8/1/2010|1170.8,9/1/2010|993.6,10/1/2010|714.9,11/1/2010|244.3," +
"12/1/2010|126.8,1/1/2011|122.1,2/1/2011|114.6,3/1/2011|185.2,4/1/2011|441.9," +
"5/1/2011|1494.9,6/1/2011|1009.9,7/1/2011|3051.3,8/1/2011|3229.7,9/1/2011|996," +
"10/1/2011|3328.7,11/1/2011|870.1,12/1/2011|1051.8,4/1/2011|481000,5/1/2011|446000," +
"6/1/2011|608000,7/1/2011|323000,8/1/2011|478000,9/1/2011|452000,10/1/2011|505000," +
"11/1/2011|438000,12/1/2011|456654";
List<DateEnergyValue> DateEnergyValues = new List<DateEnergyValue>();
// this part just generates the list of instances:
foreach(String pair in data.Split(",".ToCharArray())) {
String[] values = pair.Split("|".ToCharArray());
DateEnergyValue dev = new DateEnergyValue();
dev.CollectedDate = DateTime.ParseExact(values[0], "M/d/yyyy", null);
dev.Value = double.Parse(values[1]);
DateEnergyValues.Add(dev);
}
// you provided this part:
var minDate = DateEnergyValues.Min(a => a.CollectedDate);
var maxDate = DateEnergyValues.Max(r => r.CollectedDate);
List<DateEnergyValue> DateEnergyAverages = new List<DateEnergyValue>();
DateTime startDate = new DateTime(minDate.Year, minDate.Month, 1);
DateTime stopDate = new DateTime(maxDate.Year, maxDate.Month, 1);
while (startDate <= stopDate) {
DateEnergyValue devAverage = new DateEnergyValue();
devAverage.CollectedDate = startDate;
var monthValues = DateEnergyValues.Where(x => x.CollectedDate.Year == startDate.Year && x.CollectedDate.Month == startDate.Month);
if (monthValues.Count() > 0) {
devAverage.Value = monthValues.Average(x => x.Value);
}
DateEnergyAverages.Add(devAverage);
startDate = startDate.AddMonths(1);
}
foreach(DateEnergyValue dev in DateEnergyAverages) {
Console.WriteLine(dev);
}
}
我在类中添加了一个ToString()
,这样它就会输出:
using System;
public class DateEnergyValue
{
public DateTime CollectedDate{ get; set; }
public double Value { get; set; }
public override String ToString() {
return $"Date: {CollectedDate.ToString("M/d/yyyy")}, Value: {Value}";
}
}
生成的输出:
Date: 5/1/2009, Value: 2400
Date: 6/1/2009, Value: 2400
Date: 7/1/2009, Value: 2400
Date: 8/1/2009, Value: 7315.8
Date: 9/1/2009, Value: 5140.3
Date: 10/1/2009, Value: 1557.8
Date: 11/1/2009, Value: 1557.8
Date: 12/1/2009, Value: 369.7
Date: 1/1/2010, Value: 369.7
Date: 2/1/2010, Value: 144.8
Date: 3/1/2010, Value: 437.2
Date: 4/1/2010, Value: 804.1
Date: 5/1/2010, Value: 965.1
Date: 6/1/2010, Value: 1131
Date: 7/1/2010, Value: 1179.4
Date: 8/1/2010, Value: 1170.8
Date: 9/1/2010, Value: 993.6
Date: 10/1/2010, Value: 714.9
Date: 11/1/2010, Value: 244.3
Date: 12/1/2010, Value: 126.8
Date: 1/1/2011, Value: 122.1
Date: 2/1/2011, Value: 114.6
Date: 3/1/2011, Value: 185.2
Date: 4/1/2011, Value: 240720.95
Date: 5/1/2011, Value: 223747.45
Date: 6/1/2011, Value: 304504.95
Date: 7/1/2011, Value: 163025.65
Date: 8/1/2011, Value: 240614.85
Date: 9/1/2011, Value: 226498
Date: 10/1/2011, Value: 254164.35
Date: 11/1/2011, Value: 219435.05
Date: 12/1/2011, Value: 228852.9
我有一个想法我不确定它的性能,但我可以做到
List<DateEnergyValue> teste = new List<DateEnergyValue>();
var primeiro = teste.GroupBy(x => new { mounth = x.CollectedDate.Month })
.Select(x =>
new {
media = x.Average(p => p.Value),
mounth = x.Key.mounth
})
.ToList();
列表将按月分组,然后根据分组创建新列表,其中按月分组的平均值将产生需要月平均值的值。。。
希望这能帮助