在 MATLAB 中使用 tall 数组分析大数据
此示例说明如何在 MATLAB® 中使用 tall 数组处理大数据。您可以使用 tall 数组对无法放入内存的不同类型的数据执行各种计算。这些计算包括基本计算,以及 Statistics and Machine Learning Toolbox™ 中的机器学习算法。
此示例在一台计算机上对一小部分数据进行运算,然后扩展到分析所有数据集。不过,这种分析方法可以进一步扩展,以处理无法读入内存的大型数据集,或在像 Apache Spark™ 这样的系统上进行处理。
tall 数组简介
tall 数组和 tall 表用于处理包含任意行数的无法放入内存的数据。使用 tall 数组和表,您能够以类似内存 MATLAB® 数组的方式处理大型数据集,而不必为超大的数据量专门编写代码。不同之处在于,tall
数组在您请求执行计算之前通常不执行计算。
这种延迟计算使 MATLAB 能够尽可能合并排队的计算,并执行最少次数的数据遍历操作。由于遍历数据的次数会极大地影响执行时间,建议仅在必要时才请求输出。
为文件集合创建数据存储
创建数据存储使您能够访问数据集合。数据存储可以处理任意大的数据量,数据甚至可以分布在多个文件夹的多个文件中。您可以为大多数类型的文件创建数据存储,包括表格文本文件(此处演示)、电子表格、图像、SQL 数据库(需要 Database Toolbox™)或 Hadoop® 序列文件等的集合。
为包含航班数据的 .csv
文件创建一个数据存储。将 'NA'
值视为缺失,以便 tabularTextDatastore
用 NaN
值替换它们。选择关注的变量,并为 Origin
和 Dest
变量指定分类数据类型。预览内容。
ds = tabularTextDatastore('airlinesmall.csv'); ds.TreatAsMissing = 'NA'; ds.SelectedVariableNames = {'Year','Month','ArrDelay','DepDelay','Origin','Dest'}; ds.SelectedFormats(5:6) = {'%C','%C'}; pre = preview(ds)
pre=8×6 table
Year Month ArrDelay DepDelay Origin Dest
____ _____ ________ ________ ______ ____
1987 10 8 12 LAX SJC
1987 10 8 1 SJC BUR
1987 10 21 20 SAN SMF
1987 10 13 12 BUR SJC
1987 10 4 -1 SMF LAX
1987 10 59 63 LAX SJC
1987 10 3 -2 SAN SFO
1987 10 11 -1 SEA LAX
创建 tall 数组
除了可以包含任意数量的行以外,tall 数组与内存 MATLAB 数组并无不同。tall 数组可以包含数值、逻辑值、日期时间、持续时间、calendarDuration、分类或字符串数据。此外,您也可以将任何内存数组转换为 tall 数组。(内存数组 A
必须是受支持的数据类型之一。)
tall 数组的基础类基于支持它的数据存储的类型。例如,如果数据存储 ds
包含表格数据,则 tall(ds)
返回包含这些数据的 tall 表。
tt = tall(ds)
tt = Mx6 tall table Year Month ArrDelay DepDelay Origin Dest ____ _____ ________ ________ ______ ____ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? : : : : : : : : : : : :
显示内容指示基础数据类型,并包括前几行数据。表的大小显示为“M×6”,表示 MATLAB 尚不了解有多少行数据。
对 tall 数组执行计算
您可以像处理内存 MATLAB 数组和表一样,处理 tall 数组和 tall 表。
tall 数组的一个重要特征是,在处理它们时,MATLAB 不会立即执行大多数运算。这些运算看起来执行速度很快,是因为实际计算被延迟,直到特别请求输出时才执行计算。这种延迟计算非常重要,因为对一个包含十亿行的 tall 数组执行一个类似 size(X)
的简单命令都是一次耗时的计算过程。
当您处理 tall 数组时,MATLAB 会跟踪要执行的所有运算并优化数据遍历次数。因此,通常情况下应使用未经计算的 tall 数组,并仅在需要时请求输出。在您请求计算和显示数组之前,MATLAB 不知道未计算的 tall 数组的内容或大小。
计算离港延误均值。
mDep = mean(tt.DepDelay,'omitnan')
mDep = tall double ?
将结果收集到工作区中
延迟计算的好处是,当到了 MATLAB 执行计算的时间,通常可以合并多个运算,这样能最大限度地降低遍历数据的次数。因此,即使您执行大量运算,MATLAB 也仅在绝对必要时才会对数据进行额外次数的遍历。
gather
函数强制执行所有排队的运算,并将生成的输出载入内存中。由于 gather
在 MATLAB 中返回整个结果,因此应确保结果可放入内存中。例如,对使用 sum
、min
和 mean
等函数进行了归约的 tall 数组使用 gather
。
使用 gather
计算离港延误均值并将计算结果放入内存中。此计算只需遍历一次数据,但其他计算可能需要多次遍历数据。MATLAB 确定计算的最佳遍历次数,并在命令行中显示该信息。
mDep = gather(mDep)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 2: Completed in 0.59 sec - Pass 2 of 2: Completed in 0.53 sec Evaluation completed in 1.5 sec
mDep = 8.1860
选择 tall 数组的子集
您可以通过下标或索引从 tall 数组中提取值。您可以从顶部或底部开始对数组进行索引,或使用逻辑索引对数组进行索引。函数 head
和 tail
可以替代索引,您可以用它们来探查 tall 数组的开头部分和结尾部分。同时收集这两个变量可避免对数据进行多余的遍历。
h = head(tt); tl = tail(tt); [h,tl] = gather(h,tl)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 1: Completed in 0.5 sec Evaluation completed in 0.61 sec
h=8×6 table
Year Month ArrDelay DepDelay Origin Dest
____ _____ ________ ________ ______ ____
1987 10 8 12 LAX SJC
1987 10 8 1 SJC BUR
1987 10 21 20 SAN SMF
1987 10 13 12 BUR SJC
1987 10 4 -1 SMF LAX
1987 10 59 63 LAX SJC
1987 10 3 -2 SAN SFO
1987 10 11 -1 SEA LAX
tl=8×6 table
Year Month ArrDelay DepDelay Origin Dest
____ _____ ________ ________ ______ ____
2008 12 14 1 DAB ATL
2008 12 -8 -1 ATL TPA
2008 12 1 9 ATL CLT
2008 12 -8 -4 ATL CLT
2008 12 15 -2 BOS LGA
2008 12 -15 -1 SFO ATL
2008 12 -12 1 DAB ATL
2008 12 -1 11 ATL IAD
在扩展到完整数据集之前,请使用 head
从针对原型代码的数据中选择包含 10000 行数据的子集。
ttSubset = head(tt,10000);
按条件选择数据
您可以对 tall 数组使用典型的逻辑运算,这对于使用逻辑索引选择相关数据或删除离群值非常有用。逻辑表达式会创建一个 tall 逻辑向量,然后系统使用它进行下标索引,从而标识条件为 true 的行。
通过将分类变量 Origin
的元素与值 'BOS'
进行比较,仅选择飞离波士顿的航班。
idx = (ttSubset.Origin == 'BOS');
bosflights = ttSubset(idx,:)
bosflights = 207x6 tall table Year Month ArrDelay DepDelay Origin Dest ____ _____ ________ ________ ______ ____ 1987 10 -8 0 BOS LGA 1987 10 -13 -1 BOS LGA 1987 10 12 11 BOS BWI 1987 10 -3 0 BOS EWR 1987 10 -5 0 BOS ORD 1987 10 31 19 BOS PHL 1987 10 -3 0 BOS CLE 1987 11 5 5 BOS STL : : : : : : : : : : : :
您可以使用相同的索引方法从 tall 数组中删除包含缺失数据或 NaN 值的行。
idx = any(ismissing(ttSubset),2); ttSubset(idx,:) = [];
确定最大延误
由于大数据的性质,使用 sort
或 sortrows
等传统方法对所有数据进行排序的效率比较低。但是,用于 tall 数组的 topkrows
函数会以排序后的顺序返回前 k
行。
计算前 10 大离港延误。
biggestDelays = topkrows(ttSubset,10,'DepDelay');
biggestDelays = gather(biggestDelays)
Evaluating tall expression using the Local MATLAB Session: Evaluation completed in 0.052 sec
biggestDelays=10×6 table
Year Month ArrDelay DepDelay Origin Dest
____ _____ ________ ________ ______ ____
1988 3 772 785 ORD LEX
1989 3 453 447 MDT ORD
1988 12 397 425 SJU BWI
1987 12 339 360 DEN STL
1988 3 261 273 PHL ROC
1988 7 261 268 BWI PBI
1988 2 257 253 ORD BTV
1988 3 236 240 EWR FLL
1989 2 263 227 BNA MOB
1989 6 224 225 DFW JAX
可视化 tall 数组中的数据
对于大型数据集而言,绘制其中的每个数据点并不可行。因此,tall 数组的可视化需要使用采样或分 bin 来减少数据点的数量。
使用直方图可视化每年的航班数量。可视化函数会在您调用它们时立即遍历数据并计算解,因此不需要 gather
。
histogram(ttSubset.Year,'BinMethod','integers')
Evaluating tall expression using the Local MATLAB Session: Evaluation completed in 0.23 sec
xlabel('Year') ylabel('Number of Flights') title('Number of Flights by Year, 1987 - 1989')
扩展到整个数据集
除了使用从 head
返回的较小数据之外,您还可以使用 tall(ds)
的结果来扩展到对整个数据集执行计算。
tt = tall(ds); idx = any(ismissing(tt),2); tt(idx,:) = []; mnDelay = mean(tt.DepDelay,'omitnan'); biggestDelays = topkrows(tt,10,'DepDelay'); [mnDelay,biggestDelays] = gather(mnDelay,biggestDelays)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 2: Completed in 0.29 sec - Pass 2 of 2: Completed in 0.43 sec Evaluation completed in 0.82 sec
mnDelay = 8.1310
biggestDelays=10×6 table
Year Month ArrDelay DepDelay Origin Dest
____ _____ ________ ________ ______ ____
1991 3 -8 1438 MCO BWI
1998 12 -12 1433 CVG ORF
1995 11 1014 1014 HNL LAX
2007 4 914 924 JFK DTW
2001 4 887 884 MCO DTW
2008 7 845 855 CMH ORD
1988 3 772 785 ORD LEX
2008 4 710 713 EWR RDU
1998 10 679 673 MCI DFW
2006 6 603 626 ABQ PHX
histogram(tt.Year,'BinMethod','integers')
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 2: Completed in 0.58 sec - Pass 2 of 2: Completed in 0.3 sec Evaluation completed in 0.97 sec
xlabel('Year') ylabel('Number of Flights') title('Number of Flights by Year, 1987 - 2008')
使用 histogram2
进一步按月细分整个数据集的航班数量。由于 Month
和 Year
的 bin 事先已知,请指定 bin 边界以避免多余的数据遍历。
year_edges = 1986.5:2008.5; month_edges = 0.5:12.5; histogram2(tt.Year,tt.Month,year_edges,month_edges,'DisplayStyle','tile')
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 1: Completed in 0.49 sec Evaluation completed in 0.56 sec
colorbar xlabel('Year') ylabel('Month') title('Airline Flights by Month and Year, 1987 - 2008')
使用 tall 数组进行数据分析和机器学习
使用 Statistics and Machine Learning Toolbox™ 中的函数,您可以对 tall 数组执行更复杂的统计分析,包括计算预测分析和执行机器学习。
有关详细信息,请参阅使用 tall 数组的大数据分析 (Statistics and Machine Learning Toolbox)。
扩展到大数据系统
MATLAB 中 tall 数组的一个关键功能是与大数据平台的连接,例如计算集群和 Apache Spark™。
此示例仅粗略涉及如何使用 tall 数组处理大数据。有关使用以下产品的详细信息,请参阅Extend Tall Arrays with Other Products:
Statistics and Machine Learning Toolbox™
Database Toolbox™
Parallel Computing Toolbox™
MATLAB® Parallel Server™
MATLAB Compiler™