简体   繁体   English

时间序列统计algrothim在C#中生成递归数据结构

[英]time-series statistics algrothim to generate recursive datastructure in C#

I have a list of values, could be doubles or DateTimes. 我有一个值列表,可以是双打或DateTimes。

15, 36, -7, 12, 8 15,36,-7,12,8

This data is a TimeSeries, so order matters. 这个数据是TimeSeries,所以顺序很重要。 Also there are only 3 to 6 values in the list, so we are not talking about a large data set. 此外,列表中只有3到6个值,因此我们不是在讨论大型数据集。

Say I want to produce statistics on these, such as ratios. 假设我想生成有关这些的统计数据,例如比率。

15/36, 36/-7, -7/12, 12/8 == .417, -5.14, -.583, 1.5 15 / 36,36 / -7,-7 / 12,12 / 8 == .417,-5.14,-.583,1.5

and then ratios of the ratios 然后比率的比率

.417/-5.14, -5.14/-.583, -.583/1.5 .417 / -5.14,-5.14 / - .583,-.583 / 1.5

.. and so on. .. 等等。

I also need to generate stats for each value against each value in the past. 我还需要针对过去的每个值为每个值生成统计数据。

12/8, -7/8, 36/8, 15/8 12/8,-7 / 8,36 / 8,15 / 8

12/-7, 12/36, 12/15 12 / -7,12 / 36,12 / 15

... ...

Also need ratios of each values to average of previous values. 还需要将每个值的比率与先前值的平均值进行比较。

avg(12,-7) / 8 , avg(12,-7,36) / 8 平均(12,-7)/ 8,平均(12,-7,36)/ 8

When data is DateTime will be using TimeSpan. 当数据是DateTime时将使用TimeSpan。 Also need slope, average slope, trend of ratios, trend of slope.. etc.. 还需要坡度,平均坡度,比例趋势,坡度趋势等。

Basically trying to get as much relevant data as possible. 基本上试图获得尽可能多的相关数据。 Since its a timeseries, relevant data is restricted to statistics on values to the left of each, as well as the first and last value. 由于它是一个时间序列,相关数据仅限于每个值左侧的值的统计数据,以及第一个和最后一个值。

not sure if im looking for a design pattern, a math formula or TimeSeries analysis concepts. 不确定我是否正在寻找设计模式,数学公式或TimeSeries分析概念。

My current design is to do it in steps. 我目前的设计是分步进行。 A class for ratios of each pair, then a class for ratios of ratios.. etc. Looking for something more abstract. 每对比率的类,然后是比率比率等等。寻找更抽象的东西。

Is there a design pattern, math formula or TimeSeries concept that would enable me to write a more abstract solution to my problem? 是否有设计模式,数学公式或TimeSeries概念,使我能够为我的问题编写更抽象的解决方案?

Thanks Stack Overflow! 谢谢Stack Overflow!

I think you need to start with abstracting your time series list of numbers. 我想你需要从抽象你的时间序列数字列表开始。 It seems that each set of calculations has to traverse the list differently. 似乎每组计算都必须以不同的方式遍历列表。

interface IMyList<T>
{
    void SetList(IList<T> series);

    bool IsDone();
    T GetOperand1();
    T GetOperand2();
    T Calculate(T op1, T op2);
    void SetResult(T result);
    void Next();

    Dictionary<int, IList<T>> GetResults();
}

When you implement each IMyList in each of you classes, you will build into the class exactly how the list should be traversed. 当您在每个类中实现每个IMyList时,您将在类中构建应该遍历列表的方式。 I've implemented the your first example. 我已经实现了你的第一个例子。 Also notice I did not use recursion. 另请注意我没有使用递归。 For each type of traversal and calculation you could create a class like this: 对于每种类型的遍历和计算,您可以创建一个这样的类:

public class Ratio : IMyList<double>
{
    private Dictionary<int, IList<double>> _results;
    private int _currentSeries;
    private int _seriesResults;
    private int _op1Index;
    private int _op2Index;
    private bool _bDone;

    public Ratio()
    {
        _op1Index = 0;
        _op2Index = 1;
        _currentSeries = 0;
        _seriesResults = 1;
    }

    public void SetList(IList<double> series)
    {
        // the zero entry is the first result set
        _results = new Dictionary<int, IList<double>>();
        _results.Add(_currentSeries, series);
        _results.Add(_seriesResults, new List<double>());
    }

    public bool IsDone()
    {
        return _bDone;
    }

    public double GetOperand1()
    {
        return _results[_currentSeries][_op1Index];
    }

    public double GetOperand2()
    {
        return _results[_currentSeries][_op2Index];
    }

    public double Calculate(double op1, double op2)
    {
        return op1 / op2;
    }

    public void SetResult(double result)
    {
        _results[_seriesResults].Add(result);
    }

    public void Next()
    {
        _op1Index++;
        _op2Index++;

        if (_op2Index >= _results[_currentSeries].Count())
        {
            if (_results[_seriesResults].Count == 1)
            {
                _bDone = true;
            }
            else
            {
                _currentSeries++;
                _seriesResults++;
                _results.Add(_seriesResults, new List<double>());
                _op1Index = 0;
                _op2Index = 1;
            }
        }
    }

    public Dictionary<int, IList<double>> GetResults()
    {
        return _results;
    }
}

To put this in action, the code would be: 为了实现这一点,代码将是:

        List<double> firstList = new List<double>() { 15, 36, -7, 12, 8 };

        // the following section could be refactored further by putting the classes
        // in a list of IMyList and then looping through it
        var rat = new Ratio();
        rat.SetList(firstList);
        while (!rat.IsDone())
        {
            double op1 = rat.GetOperand1();
            double op2 = rat.GetOperand2();
            rat.SetResult(rat.Calculate(op1, op2);
            rat.Next();
        }
        var results = rat.GetResults();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM