Miguel Moura
Miguel Moura

Reputation: 39364

Create List of Time Series

I need to create a time series with 200 observations of 10 MeasureTypes (1 to 10) and join everything in a list (using 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). ...

What changes from measure to measure is the MeasureId which is incremental and the parameters (80 and 40) to (20 and 30) to ...

Is there a way to simplify this code?

Upvotes: 1

Views: 581

Answers (4)

Cetin Basoz
Cetin Basoz

Reputation: 23797

You can do something like this:

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]) }));

Upvotes: 1

mukh1n
mukh1n

Reputation: 158

  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;
    }
  }

Upvotes: 0

Chris Pickford
Chris Pickford

Reputation: 8991

Not sure how you are calculating Measure.Value, however you can use a SelectMany to effectively CROSS JOIN two enumerations together:

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
    });

Upvotes: 0

EvilTak
EvilTak

Reputation: 7579

Use a for loop with an array (or list) of tuples or a custom type to hold the parameters, like the following:

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)
});

You can use C# 7's sugared tuple syntax if you want, I aren't that well versed with it yet.

If your parameters are part of a series, you can skip the tuples entirely.

LINQ version borrowed and modified from @ChrisPickford's answer.

Upvotes: 2

Related Questions