创建时间序列列表

时间:2017-03-28 11:10:31

标签: c#

我需要创建一个包含10个MeasureTypes(1到10)的200个观测值的时间序列,并将所有内容连接到一个列表中(使用C#7):

var a = Enumerable.Range(1, 200).Select(x => new Measure { MeasureTypeId = 1, Created = DateTime.Now.AddDays(x), Value = (Decimal)(80 * random.NextDouble() + 40) });

var b = Enumerable.Range(1, 200).Select(x => new Measure { MeasureTypeId = 2, Created = DateTime.Now.AddDays(x), Value = (Decimal)(20 * random.NextDouble() + 30) });

// Other measures

var result = a.Union(b).Union(c). ...

从度量到度量的变化是MeasureId是增量的,参数(80和40)到(20和30)到......

有没有办法简化这段代码?

4 个答案:

答案 0 :(得分:2)

使用带有元组数组(或列表)或自定义类型的for循环来保存参数,如下所示:

var result = Set.Empty; // Or whatever you use

Tuple<int, int>[] params = {
    new Tuple<int, int>(80, 40),
    new Tuple<int, int>(20, 30),
    // and so on
}

for(int i = 0; i < N; i++) {
    result.Union(Enumerable.Range(1, 200).Select(x => new Measure { MeasureTypeId = i + 1, Created = DateTime.Now.AddDays(x), Value = (Decimal)(params[i].Item1 * random.NextDouble() + params[i].Item2) }));
}

// LINQ version
var result = Enumerable.Range(1, N).SelectMany(x => Enumerable.Range(1, 200), (t, n) => new Measure {
    MeasureTypeId = t,
    Created = DateTime.Now.AddDays(n),
    Value = (decimal)(params[t - 1].Item1 * random.NextDouble() + params[t - 1].Item2)
});

如果你愿意,你可以使用C#7的加糖元组语法,我还不熟悉它。

如果您的参数是系列的一部分,则可以完全跳过元组。

@ChrisPickford's answer借用和修改的LINQ版本。

答案 1 :(得分:1)

您可以这样做:

var random = new Random();
int[] multipliers = { 80, 20, 30, 50 };
int[] add = { 40, 30, 10, 20 };
var result = Enumerable.Range(1,4).SelectMany(t => 
    Enumerable.Range(1, 200).Select(x => 
        new Measure { 
        MeasureTypeId = t, 
        Created = DateTime.Now.AddDays(x), 
        Value = (Decimal)(multipliers[t-1] * random.NextDouble() + add[t-1]) }));

答案 2 :(得分:0)

不确定如何计算Measure.Value,但是您可以使用SelectMany有效CROSS JOIN两个枚举:

var result = Enumerable.Range(1, 10)
    .SelectMany(x => Enumerable.Range(1, 200), (t, n) => new Measure {
        MeasureId = ((t - 1) * 200) + n,
        MeasureTypeId = t,
        Created = DateTime.Now.AddDays(n),
        Value = (decimal)(80 * random.NextDouble() + 40) // Replace with your logic
    });

答案 3 :(得分:0)

  public class MeasurementType
  {
    public int Id { get; set; }
    public int Parameter1 { get; set; }
    public int Parameter2 { get; set; }
  }

  public class Measurement
  {
    public int MeasureTypeId { get; set; }
    public DateTime Created { get; set; }
    public decimal Value { get; set; }
  }

  public class MeasurementGenerator
  {
    private List<MeasurementType> MeasurementTypes
    {
      get
      {
        return new List<MeasurementType>
        {
          new MeasurementType() {Id = 1, Parameter1 = 80, Parameter2 = 40},
          new MeasurementType() {Id = 2, Parameter1 = 20, Parameter2 = 30},
          new MeasurementType() {Id = 3, Parameter1 = 10, Parameter2 = 50},
          new MeasurementType() {Id = 4, Parameter1 = 15, Parameter2 = 60},
          //and so on
        };
      }
    }

    public List<Measurement> GenerateMeasurements(int type)
    {
      var result = new List<Measurement>();
      for (int i = 0; i < 200; i++)
      {
        var measurementType = MeasurementTypes.First(x => x.Id == type);
        result.Add(new Measurement { MeasureTypeId = type, Created = DateTime.Now.AddDays(i), Value = measurementType.Parameter1 * random.NextDouble() + measurementType.Parameter2 });
      }
      return result;
    }
  }