/// <summary> /// コピーコンストラクタ /// </summary> /// <param name="original"></param> public TimeSeriesValues(TimeSeriesValues original) : this(original.ColumnNames) { foreach (var pair in original.Enumerate()) { this.SetValue(pair.Key, pair.Value); } }
public static TimeSeriesValues Aggregate(TimeSeriesValues seq, decimal?initialValue, Func <decimal?, decimal?, decimal?> aggregator, Func <decimal?, decimal?> finalizer) { using (seq.Lock.GetReadLock()) { TimeSeriesValues ret = new TimeSeriesValues(1); foreach (var pair in seq.Enumerate()) { decimal?aggregation = initialValue; foreach (var value in pair.Value) { aggregation = aggregator(aggregation, value); } ret[pair.Key] = new decimal?[] { finalizer(aggregation) }; } return(ret); } }
public static TimeSeriesValues OperateWith(TimeSeriesValues seq, TimeSeriesValues operand, Func <decimal?, decimal?, decimal?> operation) { if (operand == null) { throw new ArgumentNullException("operand", "'operand' cannot be null"); } int count = Math.Min(seq.ColumnCount, operand.ColumnCount); TimeSeriesValues ret = new TimeSeriesValues(seq.ColumnNames.Take(count).ToArray()); using (IEnumerator <KeyValuePair <decimal, decimal?[]> > one = seq.Enumerate().GetEnumerator()) using (IEnumerator <KeyValuePair <decimal, decimal?[]> > another = operand.Enumerate().GetEnumerator()) { bool oneAlive = one.MoveNext(); bool anotherAlive = another.MoveNext(); while (oneAlive && anotherAlive) { decimal?[] values = new decimal?[count]; for (int i = 0; i < count; i++) { if (one.Current.Value[i].HasValue && another.Current.Value[i].HasValue) { values[i] = operation(one.Current.Value[i].Value, another.Current.Value[i].Value); } } // 後にある時刻のところに値を入れる // 前にある方を進める if (one.Current.Key < another.Current.Key) { ret.SetValue(another.Current.Key, values); oneAlive = one.MoveNext(); } else { ret.SetValue(one.Current.Key, values); anotherAlive = another.MoveNext(); } } } return(ret); }
public static TimeSeriesValues AverageFlat(TimeSeriesValues seq, bool keepEmpty) { using (seq.Lock.GetReadLock()) { TimeSeriesValues ret = new TimeSeriesValues(seq.ColumnNames.Select(n => "avg " + n).ToArray()); decimal?[] tmp1 = new decimal?[seq.ColumnCount]; int[] counts = new int[seq.ColumnCount]; for (int i = 0; i < seq.ColumnCount; i++) { counts[i] = 0; } for (int i = 0; i < seq.ColumnCount; i++) { tmp1[i] = 0; } try { foreach (var pair in seq.Enumerate()) { for (int i = 0; i < pair.Value.Length; i++) { if (pair.Value[i].HasValue) { tmp1[i] += pair.Value[i].Value; counts[i]++; } } } for (int i = 0; i < seq.ColumnCount; i++) { if (counts[i] == 0) { tmp1[i] = null; } else { tmp1[i] /= counts[i]; } } } catch (OverflowException) { // doubleで集計してdecimalにキャスト double?[] tmp2 = new double?[seq.ColumnCount]; for (int i = 0; i < seq.ColumnCount; i++) { tmp2[i] = 0; } for (int i = 0; i < seq.ColumnCount; i++) { counts[i] = 0; } foreach (var pair in seq.Enumerate()) { for (int i = 0; i < pair.Value.Length; i++) { if (pair.Value[i].HasValue) { tmp2[i] += (double)pair.Value[i].Value; counts[i]++; } } } for (int i = 0; i < seq.ColumnCount; i++) { if (counts[i] == 0) { tmp1[i] = null; } else { try { tmp1[i] = (decimal)(tmp2[i] / counts[i]); } catch (OverflowException) { tmp1[i] = null; } } } } foreach (var pair in seq.Enumerate()) { decimal?[] tmp3 = new decimal?[seq.ColumnCount]; for (int i = 0; i < seq.ColumnCount; i++) { if (pair.Value[i].HasValue || !keepEmpty) { tmp3[i] = tmp1[i]; } } ret[pair.Key] = tmp3; } return(ret); } }