Main Content

从 MDF 文件中读取有效性数据

此示例说明如何从 MDF 文件中读取和使用有效性数据进行预处理。

有效性信息简介

根据 ASAM MDF 标准,“失效位”是一项可选功能,要求每条记录至少有一个额外的字节,用于将记录中的信号值标记为“失效”。这意味着每个通道的每个采样都有自己的失效位。

默认情况下,mdfRead 函数返回有效性数据,该有效性数据与失效位呈现相反的状态。也就是说,如果失效位在文件中标记为 false,指示采样有效,则 mdfRead 为对应的有效性采样返回 true 值。

mdfReadValidityRule 名称-值参量可控制有效性数据的处理方式:

  • "ignore":不读取有效性数据。

  • "include"(默认值):读取有效性数据并将其存储在时间表的 Validity 自定义属性中。

  • "replace":读取有效性数据并用 MATLAB® missing 值替换所有无效采样。(注意:整数通道会转换为 double。)

在不使用名称-值参量的情况下读取有效性数据

要从 MDF 文件中读取所有数据,请使用 mdfRead 函数,并仅将文件名作为输入参量。默认情况下,这会读取并包含有效性数据,将其存储在返回的时间表的自定义属性中。每个时间表对应于来自一个特定通道组的数据,并且包括表示该通道组的有效性数据的一个相关时间表。以下 mdfRead 调用等效于指定 ValidityRule='include'

dataWithValidity = mdfRead("VehicleDataWithInvalidSamples.mf4")
Warning: mdfRead returned data that contains invalid samples in channel groups: 1, 2. Get validity data for a channel group from the timetable’s property Properties.CustomProperties.Validity.
dataWithValidity=2×1 cell array
    {100x2 timetable}
    {100x3 timetable}

chanGrp1Data = dataWithValidity{1}
chanGrp1Data=100×2 timetable
         time     Throttle    EngineRPM
        ______    ________    _________

        0 sec          50         0    
        1 sec      53.333         1    
        2 sec      56.667         2    
        3 sec          60         3    
        4 sec      63.333         4    
        5 sec      66.667         4    
        6 sec          70         6    
        7 sec      73.333         7    
        8 sec      76.667         8    
        9 sec          80         9    
        10 sec         80         9    
        11 sec         80         9    
        12 sec         80         9    
        13 sec         80         9    
        14 sec         80         9    
        15 sec         80         9    
      ⋮

mdfRead 调用中引发的警告指示通道组 1 和 2 中返回的数据都包含无效采样。要检索通道组 1 的有效性数据,请访问时间表的 Validity 自定义属性。请注意,数据时间表和有效性时间表的大小相同。有效性时间表的每个逻辑值对应于数据时间表中对应采样的有效性。

chanGrp1Validity = chanGrp1Data.Properties.CustomProperties.Validity
chanGrp1Validity=100×2 timetable
     time     Throttle    EngineRPM
    ______    ________    _________

    0 sec      true         true   
    1 sec      true         true   
    2 sec      true         true   
    3 sec      true         true   
    4 sec      true         true   
    5 sec      true         false  
    6 sec      true         true   
    7 sec      true         true   
    8 sec      true         true   
    9 sec      true         true   
    10 sec     false        false  
    11 sec     false        false  
    12 sec     false        false  
    13 sec     false        false  
    14 sec     false        false  
    15 sec     false        false  
      ⋮

有效性数据可用于手动预处理数据时间表。例如,有效性数据可用于删除通道组中包含无效采样的所有行。

validSampleRowsMask = all(chanGrp1Validity{:,:} == 1,2);
dataWithInvalidRowsRemoved = chanGrp1Data(validSampleRowsMask, :)
dataWithInvalidRowsRemoved=37×2 timetable
         time     Throttle    EngineRPM
        ______    ________    _________

        0 sec          50         0    
        1 sec      53.333         1    
        2 sec      56.667         2    
        3 sec          60         3    
        4 sec      63.333         4    
        6 sec          70         6    
        7 sec      73.333         7    
        8 sec      76.667         8    
        9 sec          80         9    
        31 sec     63.684        31    
        32 sec     59.474        32    
        33 sec     55.263        33    
        34 sec     51.053        34    
        35 sec     46.842        35    
        36 sec     42.632        36    
        37 sec     38.421        37    
      ⋮

忽略有效性数据

当您的分析不需要有效性数据时,要节省内存和处理时间,请使用参量 ValidityRule="ignore"

dataValidityIgnored = mdfRead("VehicleDataWithInvalidSamples.mf4", ValidityRule="ignore", GroupNumber=1)
dataValidityIgnored = 1x1 cell array
    {100x2 timetable}

请注意,时间表不包含 Validity 自定义属性。

dataValidityIgnored{1}.Properties
ans = 
  TimetableProperties with properties:

             Description: ''
                UserData: []
          DimensionNames: {'time'  'Variables'}
           VariableNames: {'Throttle'  'EngineRPM'}
           VariableTypes: ["double"    "double"]
    VariableDescriptions: {'Throttle'  'EngineRPM'}
           VariableUnits: {'*10^2'  '*10^2'}
      VariableContinuity: []
                RowTimes: [100x1 duration]
               StartTime: 0 sec
              SampleRate: 1
                TimeStep: 1 sec
                  Events: [0x8 eventtable]
        CustomProperties: No custom properties are set.
      Use addprop and rmprop to modify CustomProperties.

在使用 "replace" 的情况下读取有效性数据

dataInvalidReplaced = mdfRead("VehicleDataWithInvalidSamples.mf4", ValidityRule="replace", GroupNumber=1)
dataInvalidReplaced = 1x1 cell array
    {100x2 timetable}

所有无效采样现在都已替换为 missing 值。例如,"EngineRPM" 通道在 t=5 秒处包含无效采样,因此值为 NaN。

dataInvalidReplaced{1}
ans=100×2 timetable
         time     Throttle    EngineRPM
        ______    ________    _________

        0 sec          50          0   
        1 sec      53.333          1   
        2 sec      56.667          2   
        3 sec          60          3   
        4 sec      63.333          4   
        5 sec      66.667        NaN   
        6 sec          70          6   
        7 sec      73.333          7   
        8 sec      76.667          8   
        9 sec          80          9   
        10 sec        NaN        NaN   
        11 sec        NaN        NaN   
        12 sec        NaN        NaN   
        13 sec        NaN        NaN   
        14 sec        NaN        NaN   
        15 sec        NaN        NaN   
      ⋮

预处理数据

MATLAB 提供多种处理时间表中缺失值的函数,例如 fillmissing。当填充方法设置为 'linear' 时,此函数通过对相邻的非缺失值(有效采样)进行线性插值为无效采样设置新值。

dataPreprocessed = fillmissing(dataInvalidReplaced{1}, 'linear')
dataPreprocessed=100×2 timetable
         time     Throttle    EngineRPM
        ______    ________    _________

        0 sec          50         0    
        1 sec      53.333         1    
        2 sec      56.667         2    
        3 sec          60         3    
        4 sec      63.333         4    
        5 sec      66.667         5    
        6 sec          70         6    
        7 sec      73.333         7    
        8 sec      76.667         8    
        9 sec          80         9    
        10 sec     82.149        10    
        11 sec     84.298        11    
        12 sec     86.447        12    
        13 sec     88.596        13    
        14 sec     90.746        14    
        15 sec     92.895        15    
      ⋮

有关预处理数据的详细信息,请参阅数据的预处理

Throttle 通道的直观比较

针对原始数据(存在于文件中)和使用无效采样的新值已进行线性插值的数据,绘制 "Throttle" 通道对时间通道的图。

subplot(2, 1, 1)
plot(chanGrp1Data.time, chanGrp1Data.Throttle, "r")
title("Throttle Signal as Represented in the File", "FontWeight", "bold")
xlabel("Timestamp")
ylabel("Throttle")
subplot(2, 1, 2)
plot(dataPreprocessed.time, dataPreprocessed.Throttle, "b")
title("Throttle Signal with Invalid Samples Replaced with Linearly Interpolated Values", "FontWeight", "bold")
xlabel("Timestamp")
ylabel("Throttle")

Figure contains 2 axes objects. Axes object 1 with title Throttle Signal as Represented in the File, xlabel Timestamp, ylabel Throttle contains an object of type line. Axes object 2 with title Throttle Signal with Invalid Samples Replaced with Linearly Interpolated Values, xlabel Timestamp, ylabel Throttle contains an object of type line.

结论

根据您的需要使用 ValidityRule 选项:

  • 当有效性数据与您的分析无关时,请使用 "ignore" 以节省内存和处理时间。

  • 当要手动处理无效采样时,请使用 "include"。

  • 当使用 "fillmissing" 或 rmmissing 等函数处理无效采样时,为方便起见,请使用 replace