Main Content

使用 MDF 数据存储和 tall 数组分析数据

此示例说明如何使用 tall 数组和 MDF 数据存储功能来处理大型数据集。tall 数组通常用于对无法放入内存的不同类型的数据执行计算。

此示例首先对一小部分数据进行运算,然后扩展分析整个数据集。虽然此处使用的数据集可能不代表现实应用程序中的实际大小,但同样的分析方法可以进一步扩展以处理大到无法读入内存的数据集。

要了解有关 tall 数组的详细信息,请参阅示例在 MATLAB 中使用 tall 数组分析大数据

tall 数组简介

tall 数组和 tall 表用于处理可能具有任意行数的无法放入内存的数据。使用 tall 数组和表,您可以用类似于处理内存 MATLAB 数组的方式处理大型数据集。

不同之处在于,tall 数组在您请求之前通常不执行计算。这种延迟计算使 MATLAB 能够尽可能合并排队的计算,并执行最少次数的数据遍历操作。

创建 MDF 数据存储

MDF 数据存储可用于读取和处理作为单个实体存储在多个 MDF 文件中的同构数据。如果数据集太大而无法放入内存中,数据存储还可以将数据集分成更小的块,单独放入内存中。此功能可以通过 tall 数组进一步扩展,tall 数组支持使用常用函数处理由数据存储保存的无法放入内存的数据。

在当前工作流目录中选择 MDF 文件 EngineData_MDF_TallArray.mf4,使用 mdfDatastore 函数创建一个 MDF 数据存储。此文件包含从一个 Simulink 模型记录的时间戳数据,该模型表示连接到测功机的发动机被控对象和控制器。

mds = mdfDatastore("EngineData_MDF_TallArray.mf4")
mds = 
  MDFDatastore with properties:

  Datastore Details
                         Files: {
                                ' ...\michellw.Bdoc24a_MDF\vnt-ex08773747\EngineData_MDF_TallArray.mf4'
                                }
                 ChannelGroups: 
                                  GroupNumber    AcquisitionName     Comment          ... and 10 more columns    
                                  ___________    _______________    __________                

                                       1         {[<undefined>]}    {[Python]}                


                      Channels: 
                                       Name          GroupNumber    DisplayName        ... and 17 more columns    
                                  _______________    ___________    ___________                

                                  "EngineSpeed"           1             ""                     
                                  "EngineTorque"          1             ""                     
                                  "TorqueCommand"         1             ""                     

                                ... and 1 more rows

  Options
          SelectedChannelNames: {
                                'EngineSpeed';
                                'EngineTorque';
                                'TorqueCommand'
                                 ... and 1 more
                                }
    SelectedChannelGroupNumber: 1
                      ReadSize: "file"
                       ReadRaw: 0

可以进一步配置 MDF 数据存储,以控制从 MDF 文件中读取哪些数据以及如何读取这些数据。默认情况下,选择第一个通道组,并读取该组中的所有通道。

mds.SelectedChannelGroupNumber
ans = 1
mds.SelectedChannelNames
ans = 4×1 string
    "EngineSpeed"
    "EngineTorque"
    "TorqueCommand"
    "t"

将 MDF 数据存储配置为仅选择三个感兴趣的变量:EngineSpeedTorqueCommandEngineTorque

mds.SelectedChannelNames = ["EngineSpeed", "TorqueCommand", "EngineTorque"]
mds = 
  MDFDatastore with properties:

  Datastore Details
                         Files: {
                                ' ...\michellw.Bdoc24a_MDF\vnt-ex08773747\EngineData_MDF_TallArray.mf4'
                                }
                 ChannelGroups: 
                                  GroupNumber    AcquisitionName     Comment          ... and 10 more columns    
                                  ___________    _______________    __________                

                                       1         {[<undefined>]}    {[Python]}                


                      Channels: 
                                       Name          GroupNumber    DisplayName        ... and 17 more columns    
                                  _______________    ___________    ___________                

                                  "EngineSpeed"           1             ""                     
                                  "EngineTorque"          1             ""                     
                                  "TorqueCommand"         1             ""                     

                                ... and 1 more rows

  Options
          SelectedChannelNames: {
                                'EngineSpeed';
                                'TorqueCommand';
                                'EngineTorque'
                                }
    SelectedChannelGroupNumber: 1
                      ReadSize: "file"
                       ReadRaw: 0

使用 preview 函数预览所选数据。

preview(mds)
ans=8×3 timetable
          t           EngineSpeed    TorqueCommand    EngineTorque
    ______________    ___________    _____________    ____________

    0 sec                     0              0           47.153   
    0 sec              2.37e-26              0           47.153   
    1.47e-05 sec        0.11056         47.158           47.158   
    8.85e-05 sec        0.66312         48.708           48.708   
    0.00010107 sec      0.75762          49.77            49.77   
    0.00010107 sec      0.75762          49.77            49.77   
    0.0001405 sec         1.053         39.967           39.967   
    0.00017993 sec       1.3482         23.143           23.143   

创建 tall 数组

除了可以包含任意数量的行以外,tall 数组与内存 MATLAB 数组并无不同。由于 MDF 数据存储 mds 包含带时间戳的表格数据,tall 函数会返回包含来自数据存储的数据的 tall 时间表。

tt = tall(mds)
tt =

  M×3 tall timetable

          t           EngineSpeed    TorqueCommand    EngineTorque
    ______________    ___________    _____________    ____________

    0 sec                     0              0           47.153   
    0 sec              2.37e-26              0           47.153   
    1.47e-05 sec        0.11056         47.158           47.158   
    8.85e-05 sec        0.66312         48.708           48.708   
    0.00010107 sec      0.75762          49.77            49.77   
    0.00010107 sec      0.75762          49.77            49.77   
    0.0001405 sec         1.053         39.967           39.967   
    0.00017993 sec       1.3482         23.143           23.143   
          :                :               :               :
          :                :               :               :

显示内容包括前几行数据。时间表的大小可能显示为 M×3,以表明 MATLAB 尚不知道具体行数。

对 tall 数组执行计算

您可以以处理内存 MATLAB 数组和表类似的方式处理 tall 数组和 tall 表。然而,MATLAB 不对 tall 数组执行大多数运算,而是将实际计算推迟到请求输出时进行。

使用未计算的 tall 数组并仅在需要时请求输出是很常见的。在您请求计算和显示数组之前,MATLAB 不知道未计算的 tall 数组的内容或大小。

计算 TorqueCommand 变量的中位数、最小值和最大值。请注意,不会立即计算结果。

medianTorqueCommand = median(tt.TorqueCommand)
medianTorqueCommand =

  tall double

    ?

Preview deferred. Learn more.
minTorqueCommand = min(tt.TorqueCommand)
minTorqueCommand =

  tall double

    ?

Preview deferred. Learn more.
maxTorqueCommand = max(tt.TorqueCommand)
maxTorqueCommand =

  tall double

    ?

Preview deferred. Learn more.

将结果收集到工作区中

gather 函数强制执行所有排队的运算,并将生成的输出载入内存中。

执行排队的运算 medianminmax,并计算答案。如果计算需要多次遍历数据,则 MATLAB 会确定最小遍历次数以节省执行时间,并在命令行中显示此信息。

[medianTorqueCommand, minTorqueCommand, maxTorqueCommand] = gather(medianTorqueCommand, minTorqueCommand, maxTorqueCommand)
Evaluating tall expression using the Parallel Pool 'Processes':
- Pass 1 of 4: Completed in 0.74 sec
- Pass 2 of 4: Completed in 0.37 sec
- Pass 3 of 4: Completed in 0.61 sec
- Pass 4 of 4: Completed in 0.47 sec
Evaluation completed in 3.2 sec
medianTorqueCommand = 116.2799
minTorqueCommand = 0
maxTorqueCommand = 232.9807

选择 tall 数组的子集

在扩展到完整数据集之前,请使用 head 从数据中选择一个包含 10000 行数据的子集来构建代码原型。

ttSubset = head(tt, 10000)
ttSubset =

  10,000×3 tall timetable

          t           EngineSpeed    TorqueCommand    EngineTorque
    ______________    ___________    _____________    ____________

    0 sec                     0              0           47.153   
    0 sec              2.37e-26              0           47.153   
    1.47e-05 sec        0.11056         47.158           47.158   
    8.85e-05 sec        0.66312         48.708           48.708   
    0.00010107 sec      0.75762          49.77            49.77   
    0.00010107 sec      0.75762          49.77            49.77   
    0.0001405 sec         1.053         39.967           39.967   
    0.00017993 sec       1.3482         23.143           23.143   
          :                :               :               :
          :                :               :               :

删除 tall 数组中的重复行

如果多个时间表行具有相同的行时间和数据值,则这些时间表行是重复的。使用 unique 函数从子集 tall 时间表中删除重复行。

ttSubset = unique(ttSubset)
ttSubset =

  9,968×3 tall timetable

          t           EngineSpeed    TorqueCommand    EngineTorque
    ______________    ___________    _____________    ____________

    0 sec                     0              0            47.153  
    0 sec              2.37e-26              0            47.153  
    1.47e-05 sec        0.11056         47.158            47.158  
    8.85e-05 sec        0.66312         48.708            48.708  
    0.00010107 sec      0.75762          49.77             49.77  
    0.0001405 sec         1.053         39.967            39.967  
    0.00017993 sec       1.3482         23.143            23.143  
    0.00037708 sec       2.8228         23.143         -0.021071  
          :                :               :               :
          :                :               :               :

计算引擎功率

通过公式 P [kW]=πN [rpm]T [Nm]301000EngineSpeedEngineTorque 计算发动机功率,单位为千瓦 (kW)。将结果保存到 tall 时间表中名为 EnginePower 的新变量。

ttSubset.EnginePower = (pi * ttSubset.EngineSpeed .* ttSubset.EngineTorque) / (30 * 1000)
ttSubset =

  9,968×4 tall timetable

          t           EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    ______________    ___________    _____________    ____________    ___________

    0 sec                     0              0            47.153                0
    0 sec              2.37e-26              0            47.153       1.1703e-28
    1.47e-05 sec        0.11056         47.158            47.158       0.00054599
    8.85e-05 sec        0.66312         48.708            48.708        0.0033824
    0.00010107 sec      0.75762          49.77             49.77        0.0039487
    0.0001405 sec         1.053         39.967            39.967        0.0044072
    0.00017993 sec       1.3482         23.143            23.143        0.0032675
    0.00037708 sec       2.8228         23.143         -0.021071      -6.2287e-06
          :                :               :               :               :
          :                :               :               :               :

用于 tall 数组的 topkrows 函数会在排序后返回前 k 行。获取具有最大 EnginePower 值的前 20 行。

maxEnginePower = topkrows(ttSubset, 20, "EnginePower")
maxEnginePower =

  20×4 tall timetable

        t        EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    _________    ___________    _____________    ____________    ___________

    15.17 sec        750           78.052           78.052         6.1302   
    15.16 sec        750           77.841           77.841         6.1136   
    15.15 sec        750           77.556           77.556         6.0912   
    15.14 sec        750           77.326           77.326         6.0732   
    15.18 sec        750           77.277           77.277         6.0693   
    15.13 sec        750           77.157           77.157         6.0599   
    15.12 sec        750           77.082           77.082          6.054   
    15.11 sec        750           77.067           77.075         6.0534   
        :             :               :               :               :
        :             :               :               :               :

调用 gather 函数来执行所有排队的运算并将结果收集到内存中。

[ttSubset, maxEnginePower] = gather(ttSubset, maxEnginePower)
ttSubset=9968×4 timetable
          t           EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    ______________    ___________    _____________    ____________    ___________

    0 sec                     0              0            47.153                0
    0 sec              2.37e-26              0            47.153       1.1703e-28
    1.47e-05 sec        0.11056         47.158            47.158       0.00054599
    8.85e-05 sec        0.66312         48.708            48.708        0.0033824
    0.00010107 sec      0.75762          49.77             49.77        0.0039487
    0.0001405 sec         1.053         39.967            39.967        0.0044072
    0.00017993 sec       1.3482         23.143            23.143        0.0032675
    0.00037708 sec       2.8228         23.143         -0.021071      -6.2287e-06
    0.00076951 sec       5.7492             15         -0.042938      -2.5851e-05
    0.0014014 sec        10.437             15         -0.078013      -8.5265e-05
    0.0023449 sec        17.382             15          -0.13009      -0.00023679
    0.0036773 sec        27.079             15          -0.20304      -0.00057575
    0.0054808 sec            40             15          -0.30067       -0.0012595
    0.0072843 sec        52.691             15          -0.39703       -0.0021907
    0.01 sec             71.373             15          -0.53973       -0.0040341
    0.013562 sec         95.119             15            51.176          0.50976
      ⋮

maxEnginePower=20×4 timetable
        t        EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    _________    ___________    _____________    ____________    ___________

    15.17 sec        750           78.052           78.052         6.1302   
    15.16 sec        750           77.841           77.841         6.1136   
    15.15 sec        750           77.556           77.556         6.0912   
    15.14 sec        750           77.326           77.326         6.0732   
    15.18 sec        750           77.277           77.277         6.0693   
    15.13 sec        750           77.157           77.157         6.0599   
    15.12 sec        750           77.082           77.082          6.054   
    15.11 sec        750           77.067           77.075         6.0534   
    15.1 sec         750           77.067           77.067         6.0528   
    15.09 sec        750           77.059           77.059         6.0522   
    15.08 sec        750           77.051           77.051         6.0516   
    15.07 sec        750           77.042           77.042         6.0509   
    15.06 sec        750           77.034           77.034         6.0502   
    15.05 sec        750           77.025           77.025         6.0495   
    15.04 sec        750           77.016           77.016         6.0488   
    15.03 sec        750           77.006           77.006         6.0481   
      ⋮

可视化 tall 数组中的数据

在具有两个 y 轴的图中,可视化随时间变化的 EngineTorqueEnginePower 信号。

figure
yyaxis left
plot(ttSubset.t, ttSubset.EngineTorque)
title("Engine Torque and Engine Power Over Time")
xlabel("Time")
ylabel("Engine Torque [Nm]")

yyaxis right
plot(ttSubset.t, ttSubset.EnginePower)
ylabel("Engine Power [kW]")

Figure contains an axes object. The axes object with title Engine Torque and Engine Power Over Time, xlabel Time, ylabel Engine Power [kW] contains 2 objects of type line.

扩展到整个数据集

通过使用完整的 tall 时间表,而不是从 head 返回的较小数据集,将相同的步骤扩展应用到整个数据集。

tt = tall(mds)
tt =

  M×3 tall timetable

          t           EngineSpeed    TorqueCommand    EngineTorque
    ______________    ___________    _____________    ____________

    0 sec                     0              0           47.153   
    0 sec              2.37e-26              0           47.153   
    1.47e-05 sec        0.11056         47.158           47.158   
    8.85e-05 sec        0.66312         48.708           48.708   
    0.00010107 sec      0.75762          49.77            49.77   
    0.00010107 sec      0.75762          49.77            49.77   
    0.0001405 sec         1.053         39.967           39.967   
    0.00017993 sec       1.3482         23.143           23.143   
          :                :               :               :
          :                :               :               :

首先,从 tall 时间表中删除重复行。

tt = unique(tt)
tt =

  M×3 tall timetable

    t    EngineSpeed    TorqueCommand    EngineTorque
    _    ___________    _____________    ____________

    ?         ?               ?               ?      
    ?         ?               ?               ?      
    ?         ?               ?               ?      
    :         :               :               :
    :         :               :               :

Preview deferred. Learn more.

其次,计算发动机功率,获得具有最大 EnginePower 值的前 20 行。

tt.EnginePower = (pi * tt.EngineSpeed .* tt.EngineTorque) / (30 * 1000)
tt =

  M×4 tall timetable

    t    EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    _    ___________    _____________    ____________    ___________

    ?         ?               ?               ?               ?     
    ?         ?               ?               ?               ?     
    ?         ?               ?               ?               ?     
    :         :               :               :               :
    :         :               :               :               :

Preview deferred. Learn more.
maxEnginePower = topkrows(tt, 20, "EnginePower")
maxEnginePower =

  M×4 tall timetable

    t    EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    _    ___________    _____________    ____________    ___________

    ?         ?               ?               ?               ?     
    ?         ?               ?               ?               ?     
    ?         ?               ?               ?               ?     
    :         :               :               :               :
    :         :               :               :               :

Preview deferred. Learn more.
[tt, maxEnginePower] = gather(tt, maxEnginePower)
Evaluating tall expression using the Parallel Pool 'Processes':
- Pass 1 of 1: Completed in 0.95 sec
Evaluation completed in 1.4 sec
tt=359326×4 timetable
          t           EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    ______________    ___________    _____________    ____________    ___________

    0 sec                     0              0            47.153                0
    0 sec              2.37e-26              0            47.153       1.1703e-28
    1.47e-05 sec        0.11056         47.158            47.158       0.00054599
    8.85e-05 sec        0.66312         48.708            48.708        0.0033824
    0.00010107 sec      0.75762          49.77             49.77        0.0039487
    0.0001405 sec         1.053         39.967            39.967        0.0044072
    0.00017993 sec       1.3482         23.143            23.143        0.0032675
    0.00037708 sec       2.8228         23.143         -0.021071      -6.2287e-06
    0.00076951 sec       5.7492             15         -0.042938      -2.5851e-05
    0.0014014 sec        10.437             15         -0.078013      -8.5265e-05
    0.0023449 sec        17.382             15          -0.13009      -0.00023679
    0.0036773 sec        27.079             15          -0.20304      -0.00057575
    0.0054808 sec            40             15          -0.30067       -0.0012595
    0.0072843 sec        52.691             15          -0.39703       -0.0021907
    0.01 sec             71.373             15          -0.53973       -0.0040341
    0.013562 sec         95.119             15            51.176          0.50976
      ⋮

maxEnginePower=20×4 timetable
        t         EngineSpeed    TorqueCommand    EngineTorque    EnginePower
    __________    ___________    _____________    ____________    ___________

    3819.8 sec       5000           217.53           217.53          113.9   
    3819.8 sec       5000           217.53           217.53          113.9   
    3819.8 sec       5000           217.53           217.53          113.9   
    3819.8 sec       5000           217.53           217.53          113.9   
    3819.8 sec       5000           217.53           217.53          113.9   
    3819.9 sec       5000           217.53           217.53          113.9   
    3819.9 sec       5000           217.53           217.53          113.9   
    3819.9 sec       5000           217.53           217.53          113.9   
    3819.9 sec       5000           217.52           217.52         113.89   
    3819.9 sec       5000           217.52           217.52         113.89   
    3820 sec         5000           217.52           217.52         113.89   
    3820.1 sec       5000           217.52           217.52         113.89   
    3820.2 sec       5000           217.52           217.52         113.89   
    3820.3 sec       5000           217.52           217.52         113.89   
    3820.4 sec       5000           217.52           217.52         113.89   
    3820.5 sec       5000           217.52           217.52         113.89   
      ⋮

最后,在具有两个 y 轴的图中,可视化随时间变化的 EngineTorqueEnginePower 信号。

figure
yyaxis left
plot(tt.t, tt.EngineTorque)
title("Engine Torque and Engine Power Over Time")
xlabel("Time")
ylabel("Engine Torque [Nm]")

yyaxis right
plot(tt.t, tt.EnginePower)
ylabel("Engine Power [kW]")

Figure contains an axes object. The axes object with title Engine Torque and Engine Power Over Time, xlabel Time, ylabel Engine Power [kW] contains 2 objects of type line.

关闭 MDF 文件

通过从工作区中清除 MDF 数据存储变量,关闭对 MDF 文件的访问。

clear mds