C# 在满足Deedle系列特定标准的情况下,如何累积小时数?

C# 在满足Deedle系列特定标准的情况下,如何累积小时数?,c#,time-series,deedle,C#,Time Series,Deedle,我有一个问题,我目前在Deedle解决得有点快,有点脏,但我显然没有以最有效的方式解决它 输入数据包括一些转储,其格式为,数据频率相当高,采样间隔有些随机(在~20ms到10分钟之间变化) 我想计算一个新的时间序列,其中一个或多个数据序列满足某些条件的时间(小时数)。示例:根据高于给定限制的功耗计算正常运行时间小时数 现在我已经大致解决了这个问题,首先根据值是否符合标准生成一个0或1的序列,然后将该序列插值为一个每分钟有一个值的序列,然后对每60个项目块(即每小时)计算平均值,最后使用扩展和得到

我有一个问题,我目前在Deedle解决得有点快,有点脏,但我显然没有以最有效的方式解决它

输入数据包括一些转储,其格式为
,数据频率相当高,采样间隔有些随机(在~20ms到10分钟之间变化)

我想计算一个新的时间序列,其中一个或多个数据序列满足某些条件的时间(小时数)。示例:根据高于给定限制的功耗计算正常运行时间小时数

现在我已经大致解决了这个问题,首先根据值是否符合标准生成一个0或1的序列,然后将该序列插值为一个每分钟有一个值的序列,然后对每60个项目块(即每小时)计算平均值,最后使用扩展和得到累积值

生成测试样本的代码:

// Generate some example data:
DateTime startTime = DateTime.Now.AddYears(-2);
DateTime endTime = DateTime.Now;

var rnd = new Random();
var builder = new SeriesBuilder<DateTime,double>();
var loopTime = startTime;
while (loopTime < endTime) {
    builder.Add(loopTime, rnd.NextDouble()*4000d);
    loopTime = loopTime.AddSeconds(20d + rnd.NextDouble()*100d);
}

// Accumulation criteria:
double loRange = 2000;
double hiRange = 7000;

var dataSeries = builder.Series;

var dataSeries = builder.Series;

Console.WriteLine("dataSeries contains {0} elements:", dataSeries.KeyCount);
dataSeries.Print();
然后,累积代码:

// Make new series that holds 1 if criteria is met and 0 if not:
var rawRunningStatus = dataSeries.Select(item => item.Value > loRange && item.Value <= hiRange ? 1d : 0d);

// Generate a set of timestamps for minute-interpolation:
var allMinuteTimestamps = Enumerable.Range(0, 1 + (int)endTime.Subtract(startTime).TotalMinutes)
    .Select(offset => startTime.AddMinutes(offset))
    .ToArray();

var interpolatedPerMinute = rawRunningStatus.InterpolateLinear(allMinuteTimestamps, (t1, t2) => (double)(t2 - t1).Ticks);

var runningStatusPerHour = interpolatedPerMinute.Chunk(60).Select(h => h.Value.Mean());

var hourlyTotal = Stats.expandingSum(runningStatusPerHour);

// Finally, downsample to daily values:
var total = hourlyTotal.Aggregate(
                Aggregation.ChunkWhile<DateTime>((d1, d2) => d1.Date == d2.Date),
                chunk => KeyValue.Create(chunk.Data.FirstKey().Date, OptionalValue.Create(chunk.Data.LastValue())));
total.Print();

我非常确信这可以以更好的方式解决,无论是在准确性和执行速度方面,但我还无法思考如何做到这一点,也找不到任何聚合方法,这些方法都是在序列的键而不是值部分上操作的。有什么建议吗?

一旦你有了所有的过滤时间,你就可以使用
选择
转换成一个运算值(
TimeSpan
double
或其他什么),然后简单地
Sum()
@SimpleVar我恐怕不明白你所说的过滤时间是什么意思。求和不是只返回一个标量值吗?我需要一个新的序列(在其他地方的web应用程序中以图形显示)。我完全误解了你的问题,不管怎样。一旦你有了所有的过滤时间,你可以使用
Select
转换为操作值(
TimeSpan
double
或其他什么),然后简单地
Sum()
@SimpleVar恐怕我不明白你所说的过滤时间是什么意思。求和不是只返回一个标量值吗?我需要一个新的系列(在其他地方的web应用程序中以图形显示)。我完全误解了你的问题,没关系。
// Make new series that holds 1 if criteria is met and 0 if not:
var rawRunningStatus = dataSeries.Select(item => item.Value > loRange && item.Value <= hiRange ? 1d : 0d);

// Generate a set of timestamps for minute-interpolation:
var allMinuteTimestamps = Enumerable.Range(0, 1 + (int)endTime.Subtract(startTime).TotalMinutes)
    .Select(offset => startTime.AddMinutes(offset))
    .ToArray();

var interpolatedPerMinute = rawRunningStatus.InterpolateLinear(allMinuteTimestamps, (t1, t2) => (double)(t2 - t1).Ticks);

var runningStatusPerHour = interpolatedPerMinute.Chunk(60).Select(h => h.Value.Mean());

var hourlyTotal = Stats.expandingSum(runningStatusPerHour);

// Finally, downsample to daily values:
var total = hourlyTotal.Aggregate(
                Aggregation.ChunkWhile<DateTime>((d1, d2) => d1.Date == d2.Date),
                chunk => KeyValue.Create(chunk.Data.FirstKey().Date, OptionalValue.Create(chunk.Data.LastValue())));
total.Print();
11.11.2013 00:00:00 -> 4.99771656325056 
12.11.2013 00:00:00 -> 16.9026901059461 
13.11.2013 00:00:00 -> 28.4346829644089 
14.11.2013 00:00:00 -> 40.1625579749059 
15.11.2013 00:00:00 -> 51.5181959176441 
16.11.2013 00:00:00 -> 63.3829428344991 
17.11.2013 00:00:00 -> 75.9086422691164 
18.11.2013 00:00:00 -> 87.8313912439796 
19.11.2013 00:00:00 -> 99.5987951841397 
20.11.2013 00:00:00 -> 111.948344483972 
21.11.2013 00:00:00 -> 124.061910225063 
22.11.2013 00:00:00 -> 136.246391792296 
23.11.2013 00:00:00 -> 148.16014209087  
24.11.2013 00:00:00 -> 160.765062418469 
25.11.2013 00:00:00 -> 173.016057085084 
...                 -> ...              
28.10.2015 00:00:00 -> 8598.97006880338 
29.10.2015 00:00:00 -> 8610.78890255565 
30.10.2015 00:00:00 -> 8623.3606308629  
31.10.2015 00:00:00 -> 8635.00161576886 
01.11.2015 00:00:00 -> 8647.01037016803 
02.11.2015 00:00:00 -> 8659.29864453147 
03.11.2015 00:00:00 -> 8670.50290643172 
04.11.2015 00:00:00 -> 8682.60815854525 
05.11.2015 00:00:00 -> 8694.33936107482 
06.11.2015 00:00:00 -> 8705.96593473042 
07.11.2015 00:00:00 -> 8717.99715996875 
08.11.2015 00:00:00 -> 8730.08276786404 
09.11.2015 00:00:00 -> 8741.60045331112 
10.11.2015 00:00:00 -> 8753.78545457176 
11.11.2015 00:00:00 -> 8761.26739180859