Main Content

本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

在 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' 值视为缺失,以便 tabularTextDatastoreNaN 值替换它们。选择关注的变量,并为 OriginDest 变量指定分类数据类型。预览内容。

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 中返回整个结果,因此应确保结果可放入内存中。例如,对使用 summinmean 等函数进行了归约的 tall 数组使用 gather

使用 gather 计算离港延误均值并将计算结果放入内存中。此计算只需遍历一次数据,但其他计算可能需要多次遍历数据。MATLAB 确定计算的最佳遍历次数,并在命令行中显示该信息。

mDep = gather(mDep)
Evaluating tall expression using the Local MATLAB Session:
- Pass 1 of 2: Completed in 0.87 sec
- Pass 2 of 2: Completed in 0.84 sec
Evaluation completed in 2.2 sec
mDep = 8.1860

选择 tall 数组的子集

您可以通过下标或索引从 tall 数组中提取值。您可以从顶部或底部开始对数组进行索引,或使用逻辑索引对数组进行索引。函数 headtail 可以替代索引,您可以用它们来探查 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.74 sec
Evaluation completed in 0.9 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,:) = [];

确定最大延误

由于大数据的性质,使用 sortsortrows 等传统方法对所有数据进行排序的效率比较低。但是,用于 tall 数组的 topkrows 函数会以排序后的顺序返回前 k 行。

计算前 10 大离港延误。

biggestDelays = topkrows(ttSubset,10,'DepDelay');
biggestDelays = gather(biggestDelays)
Evaluating tall expression using the Local MATLAB Session:
Evaluation completed in 0.066 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.49 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.52 sec
- Pass 2 of 2: Completed in 1.2 sec
Evaluation completed in 1.9 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 1.1 sec
- Pass 2 of 2: Completed in 0.68 sec
Evaluation completed in 2.1 sec
xlabel('Year')
ylabel('Number of Flights')
title('Number of Flights by Year, 1987 - 2008')

使用 histogram2 进一步按月细分整个数据集的航班数量。由于 MonthYear 的 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 1 sec
Evaluation completed in 1.1 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™

另请参阅

相关主题