You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#多集合合并求助:将多传感器数据合并为带补0的时间序列

合并多传感器MeasuredData集合的实现方案

嘿,这个合并传感器数据的需求我之前做项目时刚好碰到过,核心就是要把所有时间点都覆盖到,缺数据的补0对吧?我给你梳理一个清晰的实现方案,分步骤来:

核心思路

  1. 收集全量时间点:把所有传感器的MeasuredData里的Time都提取出来,去重后按时间排序,确保每个时间点都不会遗漏。
  2. 逐个时间点匹配数据:对每个时间点,检查每个传感器的数据集里是否存在对应数据,有就取Value,没有就填0。
  3. 用实体类规整合并结果(可选但推荐):定义一个专门的类来存储每个时间点的所有传感器数据,方便后续输出或处理。

代码实现

第一步:定义合并结果实体类

我们用字典来存储每个传感器的数值,键是传感器名称,值是对应时间的数值(0表示无数据):

public class MergedMeasuredData
{
    public DateTime Time { get; set; }
    public Dictionary<string, double> SensorValues { get; set; } = new Dictionary<string, double>();
}

第二步:基础合并方法

这个版本逻辑直观,适合数据量不大的场景:

public static List<MergedMeasuredData> MergeSensorData(Dictionary<string, List<MeasuredData>> sensorDataMap)
{
    // 收集所有唯一时间点并排序
    var allTimePoints = sensorDataMap.Values
        .SelectMany(data => data.Select(d => d.Time))
        .Distinct()
        .OrderBy(time => time)
        .ToList();

    var mergedData = new List<MergedMeasuredData>();

    foreach (var timePoint in allTimePoints)
    {
        var mergedEntry = new MergedMeasuredData { Time = timePoint };

        foreach (var sensorEntry in sensorDataMap)
        {
            string sensorName = sensorEntry.Key;
            List<MeasuredData> sensorData = sensorEntry.Value;

            // 查找当前传感器在该时间点的数据,没有就填0
            var dataPoint = sensorData.FirstOrDefault(d => d.Time == timePoint);
            mergedEntry.SensorValues[sensorName] = dataPoint?.Value ?? 0;
        }

        mergedData.Add(mergedEntry);
    }

    return mergedData;
}

第三步:性能优化版本

如果你的传感器数据量很大,每次用FirstOrDefault遍历查找会比较慢,我们可以提前把每个传感器的数据转成Dictionary<DateTime, double>,这样查找时间从O(n)降到O(1):

public static List<MergedMeasuredData> MergeSensorDataOptimized(Dictionary<string, List<MeasuredData>> sensorDataMap)
{
    // 提前将每个传感器的数据转为DateTime到Value的字典,提升查找性能
    var sensorDataDictMap = sensorDataMap.ToDictionary(
        k => k.Key,
        v => v.Value.ToDictionary(d => d.Time, d => d.Value)
    );

    var allTimePoints = sensorDataDictMap.Values
        .SelectMany(dict => dict.Keys)
        .Distinct()
        .OrderBy(time => time)
        .ToList();

    var mergedData = new List<MergedMeasuredData>();

    foreach (var timePoint in allTimePoints)
    {
        var mergedEntry = new MergedMeasuredData { Time = timePoint };

        foreach (var sensorEntry in sensorDataDictMap)
        {
            string sensorName = sensorEntry.Key;
            var sensorDataDict = sensorEntry.Value;

            // 尝试获取数据,不存在则返回0
            mergedEntry.SensorValues[sensorName] = sensorDataDict.TryGetValue(timePoint, out double value) ? value : 0;
        }

        mergedData.Add(mergedEntry);
    }

    return mergedData;
}

示例用法

这里模拟两个传感器的数据,看看合并后的效果:

// 模拟传感器1的数据(温度)
var sensorTempData = new List<MeasuredData>
{
    new MeasuredData(new DateTime(2024, 5, 20, 10, 0, 0), 25.5),
    new MeasuredData(new DateTime(2024, 5, 20, 10, 1, 0), 26.1)
};

// 模拟传感器2的数据(湿度)
var sensorHumidityData = new List<MeasuredData>
{
    new MeasuredData(new DateTime(2024, 5, 20, 10, 0, 0), 60.2),
    new MeasuredData(new DateTime(2024, 5, 20, 10, 2, 0), 61.0)
};

// 把传感器数据按名称存入字典
var sensorDataMap = new Dictionary<string, List<MeasuredData>>
{
    { "Sensor_Temperature", sensorTempData },
    { "Sensor_Humidity", sensorHumidityData }
};

// 调用合并方法
var mergedResult = MergeSensorDataOptimized(sensorDataMap);

// 输出合并结果
foreach (var entry in mergedResult)
{
    Console.WriteLine($"时间: {entry.Time:yyyy-MM-dd HH:mm:ss}");
    foreach (var sensorValue in entry.SensorValues)
    {
        Console.WriteLine($"  {sensorValue.Key}: {sensorValue.Value}");
    }
}

运行后输出的结果会是:

时间: 2024-05-20 10:00:00
  Sensor_Temperature: 25.5
  Sensor_Humidity: 60.2
时间: 2024-05-20 10:01:00
  Sensor_Temperature: 26.1
  Sensor_Humidity: 0
时间: 2024-05-20 10:02:00
  Sensor_Temperature: 0
  Sensor_Humidity: 61.0

这样就完美满足你的需求啦,每个时间点都包含所有传感器的数据,缺的自动补0。

内容的提问来源于stack exchange,提问作者coding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:34:08