使用 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 数据存储配置为仅选择三个感兴趣的变量:EngineSpeed
、TorqueCommand
和 EngineTorque
。
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
函数强制执行所有排队的运算,并将生成的输出载入内存中。
执行排队的运算 median
、min
、max
,并计算答案。如果计算需要多次遍历数据,则 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 : : : : : : : :
计算引擎功率
通过公式 用 EngineSpeed
和 EngineTorque
计算发动机功率,单位为千瓦 (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 轴的图中,可视化随时间变化的 EngineTorque
和 EnginePower
信号。
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]")
扩展到整个数据集
通过使用完整的 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 轴的图中,可视化随时间变化的 EngineTorque
和 EnginePower
信号。
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]")
关闭 MDF 文件
通过从工作区中清除 MDF 数据存储变量,关闭对 MDF 文件的访问。
clear mds