如何获取统计数据中的缺失点值?

时间:2011-11-12 19:52:48

标签: c# asp.net webforms statistics

我正在编写统计报告,我正在处理大量数据,所以我们只是在收集数据。例如,我们输出DateTime / Data对象并跟踪从开始日期到结束日期的月份间隔。

问题是数据只列出有数据的月份,例如它只会给出2010年2月的2011年2月和2011年8月。我需要知道如何构建它,所以我可以把0放在2011年1月, 2011年3月等等。

有人可以让我知道如何在没有大量开销的情况下构建它吗?我想先得到一个循环,然后获得必要的间隔(例如Minutes,Months,Years)并将其放入一个列表,然后当我通过我的DateTime / Data对象检查它是否大于0时替换它。这也是为了在图表上创建点。

2 个答案:

答案 0 :(得分:1)

将数据加载到链接列表中,并插入缺少的数据点:

using System;
using System.Collections.Generic;

namespace Whatever
{
  public struct DataPoint
  {
    private DateTime time;
    private int value;

    public DataPoint(DateTime time, int value)
    {
      this.time = time;
      this.value = value;
    }

    public DateTime Time
    {
      get { return this.time; }
    }

    public int Value
    {
      get { return this.value; }
    }

    public override string ToString()
    {
      return string.Format("{0:D2}/{1}: {2}", this.time.Month, this.time.Year, this.value);
    }
  }

  public static class Program
  {
    public static void Main()
    {
      // List of the datapoints, e.g. loaded from a database
      var dataPoints = new List<DataPoint>();
      dataPoints.Add(new DataPoint(new DateTime(2010, 11, 1), 10));
      dataPoints.Add(new DataPoint(new DateTime(2011,  2, 1), 20));
      dataPoints.Add(new DataPoint(new DateTime(2011,  3, 1), 30));
      dataPoints.Add(new DataPoint(new DateTime(2011,  6, 1), 40));
      dataPoints.Add(new DataPoint(new DateTime(2011,  9, 1), 50));
      dataPoints.Add(new DataPoint(new DateTime(2011, 12, 1), 60));
      dataPoints.Add(new DataPoint(new DateTime(2012,  2, 1), 70));

      // Endpoints of the measurement interval
      var begin = new DateTime(2010, 9, 1);
      var end   = new DateTime(2012, 4, 1);

      // Check each month and insert missing datapoints
      var time = begin;
      var i = 0;
      while (time <= end)
      {
        if (i < dataPoints.Count)
        {
          if (time < dataPoints[i].Time)
          {
            var dataPoint = new DataPoint(time, 0);
            dataPoints.Insert(i, dataPoint);
          }
        }
        else
        {
          var dataPoint = new DataPoint(time, 0);
          dataPoints.Add(dataPoint);
        }
        ++i;
        time = time.AddMonths(1);
      }

      // Print list
      foreach (var dataPoint in dataPoints)
        Console.WriteLine(dataPoint);
    }
  } 
}

修改 如果您只需要绘制这些数据,则无需插入缺失的数据点。我想简单地在现有点之间进行插值,我的意思是连接它们。如果现有的点用实心圆圈表示,那么缺失的点可以用空圆圈表示,坐在这些连接线上(这样的图形控件可以写入绘图给出的点,而不存储它们。)

答案 1 :(得分:1)

如果可能,我建议修改此过程的存储过程和/或SQL调用,并在部分连接(LEFT / RIGHT JOIN)和COALESCE / ISNULL函数的帮助下插入缺失的数据。

这样的事情:

DECLARE @range AS TABLE (datePoint DATETIME);
DECLARE @data AS TABLE (datePoint DATETIME, value INT);

-- setup date range
DECLARE @currentDatePoint AS DATETIME;
SET @currentDatePoint = '01/01/2011'
WHILE @currentDatePoint < '01/01/2012'
BEGIN
    INSERT INTO @range VALUES (@currentDatePoint);
    SET @currentDatePoint = DATEADD(MONTH, 1, @currentDatePoint);
END

-- setup test data
SET @currentDatePoint = '01/01/2011'
WHILE @currentDatePoint < '01/01/2012'
BEGIN
    INSERT INTO @data VALUES (@currentDatePoint, DATEPART(MONTH, @currentDatePoint));
    SET @currentDatePoint = DATEADD(MONTH, 2, @currentDatePoint);
END
--end setup

-- actual select
SELECT 
    r.datePoint, 
    ISNULL(d.value, 0) 
FROM 
    @range r
LEFT JOIN 
    @data d ON r.datePoint = d.datePoint