LINQ计算排序列表℃的移动平均线,日期时间,双> [英] LINQ to calculate a moving average of a SortedList<dateTime,double>

查看:186
本文介绍了LINQ计算排序列表℃的移动平均线,日期时间,双>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个排序列表<形式的一次系列;日期时间,双> 。我想计算这一系列的移动平均线。我可以循环做到这一点使用简单。我不知道是否有更好的方法来做到这一点使用LINQ



我的版本:

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;

命名ConsoleApplication1
{
类节目
{
静态无效的主要(字串[] args)
{
变种mySeries =新SortedList的<日期时间,双>();
mySeries.Add(新的DateTime(2011,01,1),10);
mySeries.Add(新的DateTime(2011,01,2),25);
mySeries.Add(新的DateTime(2011,01,3),30);
mySeries.Add(新日期时间(2011年,01,4),45);
mySeries.Add(新的DateTime(2011,01,5),50);
mySeries.Add(新日期时间(2011年,01,6),65);

变种Calcs(计算)=新的计算();
变种平均= calcs.MovingAverage(mySeries,3);
的foreach(以平均无功项)
{
Console.WriteLine({0} {1},item.Key,item.Value);
}
}
}
级计算
{
公众排序列表<日期时间,双>移动平均(排序列表<日期时间,双>系列,诠释期)
{
VAR的结果=新SortedList的<日期时间,双>();

的for(int i = 0; I< series.Count();我++)
{
如果(I> =时间 - 1)
{
双总= 0;
为(INT X = 1; X>(I - 期); x--)
总+ = series.Values​​ [X];
双平均=总/期;
result.Add(series.Keys [I],平均值);
}

}
返回结果;
}
}
}


解决方案

您已经有一个答案显示你如何的可以的使用L​​INQ,但坦率地说,我不会在这里使用LINQ,因为这将最有可能执行相比,当前解决方案很差,现有的代码已经是清楚了。



不过,而不是总在前面的期计算每一步的元素,你可以保持一个运行总并调整它在每次迭代。也就是说,更改此:

 总= 0; 
为(INT X = 1; X>(I - 期); x--)
总+ = series.Values​​ [X];



这样:

 如果(I> =期){
总 - = series.Values​​ [我 - 期间];
}
总+ = series.Values​​ [I]

这将意味着你的代码将采取相同的时间量,而不管执行的大小周期


I have a time series in the form of a SortedList<dateTime,double>. I would like to calculate a moving average of this series. I can do this using simple for loops. I was wondering if there is a better way to do this using linq.

my version:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var mySeries = new SortedList<DateTime, double>();
            mySeries.Add(new DateTime(2011, 01, 1), 10);
            mySeries.Add(new DateTime(2011, 01, 2), 25);
            mySeries.Add(new DateTime(2011, 01, 3), 30);
            mySeries.Add(new DateTime(2011, 01, 4), 45);
            mySeries.Add(new DateTime(2011, 01, 5), 50);
            mySeries.Add(new DateTime(2011, 01, 6), 65);

            var calcs = new calculations();
            var avg = calcs.MovingAverage(mySeries, 3);
            foreach (var item in avg)
            {
                Console.WriteLine("{0} {1}", item.Key, item.Value);                
            }
        }
    }
    class calculations
    {
        public SortedList<DateTime, double> MovingAverage(SortedList<DateTime, double> series, int period)
        {
            var result = new SortedList<DateTime, double>();

            for (int i = 0; i < series.Count(); i++)
            {
                if (i >= period - 1)
                {
                    double total = 0;
                    for (int x = i; x > (i - period); x--)
                        total += series.Values[x];
                    double average = total / period;
                    result.Add(series.Keys[i], average);  
                }

            }
            return result;
        }
    }
}

解决方案

You already have an answer showing you how you can use LINQ but frankly I wouldn't use LINQ here as it will most likely perform poorly compared to your current solution and your existing code already is clear.

However instead of calculating the total of the previous period elements on every step, you can keep a running total and adjust it on each iteration. That is, change this:

total = 0;
for (int x = i; x > (i - period); x--)
    total += series.Values[x];

to this:

if (i >= period) {
    total -= series.Values[i - period];
}
total += series.Values[i];

This will mean that your code will take the same amount of time to execute regardless of the size of period.

这篇关于LINQ计算排序列表℃的移动平均线,日期时间,双&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆