matlab.tall.reduce
通过对数据块应用归约算法来减少数组
语法
说明
[
(其中 tA
,tB
,...] = matlab.tall.reduce(fcn
,reducefcn
,tX
,tY
,...)fcn
和 reducefcn
是返回多个输出的函数)返回数组 tA,tB,...
,其中每个数组对应于 fcn
和 reducefcn
的一个输出参数。此语法具有以下要求:
fcn
返回的输出数目必须与从matlab.tall.reduce
请求的输出数目相同。reducefcn
具有的输入和输出数目必须与从matlab.tall.reduce
请求的输出数目相同。fcn
和reducefcn
的每个输出必须与第一个输入tX
的输出类型相同。fcn
和reducefcn
的对应输出必须具有相同的高度。
示例
将归约函数应用于 tall 向量
创建一个 tall 表,从该表中提取 tall 向量,然后求向量中的元素总数。
为 airlinesmall.csv
数据集创建 tall 表。该数据包含有关美国航班的到港和离港时间的信息。提取 ArrDelay
变量,该变量是到港延误的向量。
ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA'); ds.SelectedVariableNames = {'ArrDelay' 'DepDelay'}; tt = tall(ds); tX = tt.ArrDelay;
使用 matlab.tall.reduce
计算 tall 向量中非 NaN
元素的总数。第一个函数 numel
计算每个数据块中的元素数目,第二个函数 sum
将每个块的所有计数相加,以产生标量结果。
s = matlab.tall.reduce(@numel,@sum,tX)
s = MxNx... tall double array ? ? ? ... ? ? ? ... ? ? ? ... : : : : : :
将结果收集到内存中。
s = gather(s)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 1: Completed in 0.63 sec Evaluation completed in 0.77 sec
s = 123523
计算 tall 向量的均值
创建一个 tall 表,从该表中提取两个 tall 向量,然后计算每个向量的均值。
为 airlinesmall.csv
数据集创建 tall 表。该数据包含有关美国航班的到港和离港时间的信息。提取 ArrDelay
和 DepDelay
变量,这些变量是到港和离港延误的向量。
ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA'); ds.SelectedVariableNames = {'ArrDelay' 'DepDelay'}; tt = tall(ds); tt = rmmissing(tt); tX = tt.ArrDelay; tY = tt.DepDelay;
在算法的第一阶段,计算向量中每个数据块的总和及元素计数。为此,您可以编写一个函数,它接受两个输入项,返回一个输出项,该输出项包含每个输入项的总和及计数。该函数作为局部函数列在示例的末尾。
function bx = sumcount(tx,ty) bx = [sum(tx) numel(tx) sum(ty) numel(ty)]; end
在算法的归约阶段,您需要将所有中间总和与计数相加。因此,matlab.tall.reduce
返回每个输入向量的元素总和与元素个数,这样,计算均值就是简单的除法。对于此步骤,您可以将 sum
函数应用于第一阶段 1×4 向量输出的第一个维度。
reducefcn = @(x) sum(x,1); s = matlab.tall.reduce(@sumcount,reducefcn,tX,tY)
s = MxNx... tall double array ? ? ? ... ? ? ? ... ? ? ? ... : : : : : :
s = gather(s)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 1: Completed in 1.6 sec Evaluation completed in 1.8 sec
s = 1×4
860584 120866 982764 120866
s
的前两个元素是 tX
的总和与计数,后两个元素是 tY
的总和与计数。将总和与计数相除得到均值,您可以将均值与 mean
函数返回的答案进行比较。
my_mean = [s(1)/s(2) s(3)/s(4)]
my_mean = 1×2
7.1201 8.1310
m = gather(mean([tX tY]))
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 1: Completed in 0.38 sec Evaluation completed in 0.52 sec
m = 1×2
7.1201 8.1310
局部函数
此处列出的是 sumcount
函数,matlab.tall.reduce
调用该函数来计算中间总和与元素计数。
function bx = sumcount(tx,ty) bx = [sum(tx) numel(tx) sum(ty) numel(ty)]; end
按组计算统计量
创建一个 tall 表,然后计算数据中每年的航班延误均值。
为 airlinesmall.csv
数据集创建 tall 表。该数据包含有关美国航班的到港和离港时间的信息。从该表中删除缺失数据行并提取 ArrDelay
、DepDelay
和 Year
变量。这些变量是数据集中每个航班到港和离港延误以及相关年份的向量。
ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA'); ds.SelectedVariableNames = {'ArrDelay' 'DepDelay' 'Year'}; tt = tall(ds); tt = rmmissing(tt);
使用 matlab.tall.reduce
将两个函数应用于 tall 表。第一个函数合并 ArrDelay
和 DepDelay
变量来求每个航班的总延误均值。该函数确定每个数据分块中有多少唯一年份,然后循环遍历每一年并计算该年中航班总延误的平均值。结果是一个包含年份和总延误均值的二变量表。这些中间数据需要进一步约简,直到得到每年的延误均值。在您的当前文件夹中将此函数另存为 transform_fcn.m
。
type transform_fcn
function t = transform_fcn(a,b,c) ii = gather(unique(c)); for k = 1:length(ii) jj = (c == ii(k)); d = mean([a(jj) b(jj)], 2); if k == 1 t = table(c(jj),d,'VariableNames',{'Year' 'MeanDelay'}); else t = [t; table(c(jj),d,'VariableNames',{'Year' 'MeanDelay'})]; end end end
第二个函数使用第一个函数的结果来计算每年的总延误均值。reduce_fcn
的输出与 transform_fcn
的输出兼容,因此数据块可以按任意顺序串联和持续约简,直到每年只剩下一行。
type reduce_fcn
function TT = reduce_fcn(t) [groups,Y] = findgroups(t.Year); D = splitapply(@mean, t.MeanDelay, groups); TT = table(Y,D,'VariableNames',{'Year' 'MeanDelay'}); end
将变换和归约函数应用于 tall 向量。由于输入(类型 double
)和输出(类型 table
)具有不同数据类型,因此使用 'OutputsLike'
名称-值对组来指定输出是表。指定输出类型的一种简单方法是使用虚拟输入调用变换函数。
a = tt.ArrDelay;
b = tt.DepDelay;
c = tt.Year;
d1 = matlab.tall.reduce(@transform_fcn, @reduce_fcn, a, b, c, 'OutputsLike',{transform_fcn(0,0,0)})
d1 = Mx2 tall table Year MeanDelay ____ _________ ? ? ? ? ? ? : : : :
将结果收集到内存中以查看每年的总航班延误均值。
d1 = gather(d1)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 1: Completed in 1.2 sec Evaluation completed in 1.4 sec
d1=22×2 table
Year MeanDelay
____ _________
1987 7.6889
1988 6.7918
1989 8.0757
1990 7.1548
1991 4.0134
1992 5.1767
1993 5.4941
1994 6.0303
1995 8.4284
1996 9.6981
1997 8.4346
1998 8.3789
1999 8.9121
2000 10.595
2001 6.8975
2002 3.4325
⋮
替代方法
按组计算相同统计量的另一种方法是使用 splitapply
调用 matlab.tall.reduce
(而不是使用 matlab.tall.reduce
调用 splitapply
)。
使用此方法,可以直接对数据调用 findgroups
和 splitapply
。对每组数据进行操作的函数 mySplitFcn
包括对 matlab.tall.reduce
的调用。matlab.tall.reduce
使用的变换和归约函数不需要对数据进行分组,因此这些函数只对 splitapply
向其传递的预分组数据执行计算。
type mySplitFcn
function T = mySplitFcn(a,b,c) T = matlab.tall.reduce(@non_group_transform_fcn, @non_group_reduce_fcn, ... a, b, c, 'OutputsLike', {non_group_transform_fcn(0,0,0)}); function t = non_group_transform_fcn(a,b,c) d = mean([a b], 2); t = table(c,d,'VariableNames',{'Year' 'MeanDelay'}); end function TT = non_group_reduce_fcn(t) D = mean(t.MeanDelay); TT = table(t.Year(1),D,'VariableNames',{'Year' 'MeanDelay'}); end end
调用 findgroups
和 splitapply
对数据进行操作,并将 mySplitFcn
应用于每组数据。
groups = findgroups(c); d2 = splitapply(@mySplitFcn, a, b, c, groups); d2 = gather(d2)
Evaluating tall expression using the Local MATLAB Session: - Pass 1 of 2: Completed in 0.37 sec - Pass 2 of 2: Completed in 1.2 sec Evaluation completed in 2.2 sec
d2=22×2 table
Year MeanDelay
____ _________
1987 7.6889
1988 6.7918
1989 8.0757
1990 7.1548
1991 4.0134
1992 5.1767
1993 5.4941
1994 6.0303
1995 8.4284
1996 9.6981
1997 8.4346
1998 8.3789
1999 8.9121
2000 10.595
2001 6.8975
2002 3.4325
⋮
tall 向量的加权标准差和方差
使用权重向量计算 tall 数组的加权标准差和方差。以下示例说明如何使用 matlab.tall.reduce
来解决 tall 数组尚不支持的功能。
创建两个由随机数据构成的 tall 向量。tX
包含随机数据,tP
包含对应的概率,以使 sum(tP)
为 1
。这些概率适合为数据加权。
rng default tX = tall(rand(1e4,1)); p = rand(1e4,1); tP = tall(normalize(p,'scale',sum(p)));
编写一个恒等式函数,它返回的输出等于输入。此方法跳过 matlab.tall.reduce
的变换步骤,将数据直接传递到约简步骤,其中重复应用归约函数以减少数据的大小。
type identityTransform.m
function [A,B] = identityTransform(X,Y) A = X; B = Y; end
接下来,编写一个对 tall 向量块进行运算的归约函数,以计算加权方差和标准差。
type weightedStats.m
function [wvar, wstd] = weightedStats(X, P) wvar = var(X,P); wstd = std(X,P); end
使用 matlab.tall.reduce
将这些函数应用于 tall 向量中的数据块。
[tX_var_weighted, tX_std_weighted] = matlab.tall.reduce(@identityTransform, @weightedStats, tX, tP)
tX_var_weighted = MxNx... tall double array ? ? ? ... ? ? ? ... ? ? ? ... : : : : : : tX_std_weighted = MxNx... tall double array ? ? ? ... ? ? ? ... ? ? ? ... : : : : : :
输入参数
fcn
— 要应用的变换函数
函数句柄 | 匿名函数
要应用的变换函数,指定为函数句柄或匿名函数。fcn
的每个输出必须与第一个输入 tX
的类型相同。您可以使用 'OutputsLike'
选项返回不同数据类型的输出。如果 fcn
返回多个输出,则这些输出必须具有相同的高度。
fcn
的一般函数签名是
[a, b, c, ...] = fcn(x, y, z, ...)
fcn
必须满足以下要求:
输入参数 - 输入
[x, y, z, ...]
是内存数据块。通过分别从各个 tall 数组输入[tX, tY, tZ, ...]
中提取数据来生成这些数据块。输入[x, y, z, ...]
满足以下属性:在任何允许的扩展后,所有
[x, y, z, ...]
在第一个维度中具有相同的大小。[x, y, z, ...]
中的数据块来自 tall 维度中的相同索引(假设 tall 数组的 tall 维度是非单一维度)。例如,如果tX
和tY
的 tall 维度为非单一维度,则第一组数据块可能是x = tX(1:20000,:)
和y = tY(1:20000,:)
。如果任一
[tX, tY, tZ, ...]
的第一个维度的大小为1
,则对应的块[x, y, z, ...]
包含该 tall 数组中的所有数据。
输出参数 - 输出
[a, b, c, ...]
是可放入内存的数据块,将被发送到对应的输出[tA, tB, tC, ...]
。输出[a, b, c, ...]
满足以下属性:所有
[a, b, c, ...]
的第一个维度必须具有相同的大小。所有
[a, b, c, ...]
与先前对fcn
的调用的对应结果垂直串联。所有
[a, b, c, ...]
都将发送到各自目标输出数组中第一个维度中的相同索引。
函数规则 -
fcn
必须满足函数规则:F([inputs1; inputs2]) == [F(inputs1); F(inputs2)]
:将函数应用于输入的串联应该等效于将函数分别应用于各输入,然后对结果进行串联。
空输入 - 确保
fcn
可以处理高度为 0 的输入。当文件为空或者您对数据进行大量过滤时,可能会出现空输入。
例如,以下函数接受两个输入数组,对它们求平方,并返回两个输出数组:
function [xx,yy] = sqInputs(x,y) xx = x.^2; yy = y.^2; end
tX
和 tY
求平方并使用此命令求最大值:tA = matlab.tall.reduce(@sqInputs, @max, tX, tY)
示例: tC = matlab.tall.reduce(@numel,@sum,tX,tY)
求每个块中的元素数,然后将结果相加以计算元素总数。
数据类型: function_handle
reducefcn
— 要应用的归约函数
函数句柄 | 匿名函数
要应用的归约函数,指定为函数句柄或匿名函数。reducefcn
的每个输出必须与第一个输入 tX
的类型相同。您可以使用 'OutputsLike'
选项返回不同数据类型的输出。如果 reducefcn
返回多个输出,则这些输出必须具有相同的高度。
reducefcn
的一般函数签名是
[rA, rB, rC, ...] = reducefcn(a, b, c, ...)
reducefcn
必须满足以下要求:
输入参数 - 输入
[a, b, c, ...]
是可放入内存的块。数据块是fcn
返回的输出,或reducefcn
的经过部分约简的输出,需要再次进行操作以进一步约简。输入[a, b, c, ...]
满足以下属性:输入
[a, b, c, ...]
在第一个维度中具有相同的大小。对于第一个维度中的给定索引,数据块
[a, b, c, ...]
的每行都来自输入,或者来自之前对reducefcn
的相同调用。对于第一个维度中的给定索引,该索引的输入
[a, b, c, ...]
的每行都来自第一个维度中的相同索引。
输出参数 - 所有输出
[rA, rB, rC, ...]
在第一个维度中必须具有相同的大小。此外,它们必须可以与对应的输入[a, b, c, ...]
垂直串联,以便在必要时重复约简。函数规则 -
reducefcn
必须满足以下函数规则(取决于舍入误差):F(input) == F(F(input))
:将该函数重复应用于相同的输入不应改变结果。F([input1; input2]) == F([input2; input1])
:结果应该与串联顺序无关。F([input1; input2]) == F([F(input1); F(input2)])
:将函数应用于某些中间结果的串联应该等效于单独应用函数再进行串联。
空输入 - 确保
reducefcn
可以处理高度为 0 的输入。当文件为空或者您对数据进行大量过滤时,可能会出现空输入。对于此调用,在除第一个维度以外的维度中,所有输入块均为正确类型和大小的空数组。
sum
、prod
、max
等内置维度归约函数是一些合适的归约函数。这些函数可以处理由 fcn
生成的中间结果并返回单一标量。这些函数具有以下属性,即串联发生的顺序和应用归约运算的次数不会更改最终答案。有些函数,例如 mean
和 var
,通常应避免作为归约函数,因为应用归约运算的次数会更改最终答案。
示例: tC = matlab.tall.reduce(@numel,@sum,tX)
求每个块中的元素数,然后将结果相加以计算元素总数。
数据类型: function_handle
tX
, tY
— 输入数组
标量 | 向量 | 矩阵 | 多维数组
输入数组,指定为标量、向量、矩阵或多维数组。输入数组用作变换函数 fcn
的输入。每个输入数组 tX,tY,...
必须具有兼容的高度。如果两个输入具有相同的高度,或者其中一个输入的高度为 1,则它们具有兼容的高度。
PA
, PB
— 输出数组的原型
数组
输出数组的原型,指定为数组。当您指定 'OutputsLike'
时,matlab.tall.reduce
返回的输出数组 tA,tB,...
与指定的数组 {PA,PB,...}
具有相同的数据类型和属性。
示例: tA = matlab.tall.reduce(fcn,reducefcn,tX,'OutputsLike',{int8(1)});
(其中 tX
是双精度 tall 数组)以 int8
(而不是 double
)形式返回 tA
。
输出参数
tA
, tB
— 输出数组
标量 | 向量 | 矩阵 | 多维数组
输出数组,以标量、向量、矩阵或多维数组形式返回。如果 matlab.tall.reduce
的任一输入为 tall,则所有输出参数也为 tall。否则,所有输出参数均为内存数组。
输出数组的大小和数据类型取决于指定的函数 fcn
和 reducefcn
。通常,输出 tA,tB,...
必须与第一个输入 tX
具有相同的数据类型。但是,您可以指定 'OutputsLike'
以返回不同数据类型。输出数组 tA,tB,...
都具有相同的高度。
详细信息
tall 数组块
从数据存储创建 tall 数组时,基础数据存储便于在计算过程中移动数据。数据以块或分块形式的离散片段移动,其中每个块是一组可放入内存的连续行。例如,二维数组(例如表)的一个块是 X(n:m,:)
,表示下标为 n
和 m
的一些数据。每个块的大小基于数据存储的 ReadSize
属性的值,但该块不一定完全等于该大小。对于 matlab.tall.reduce
来说,tall 数组被视为许多此类块的垂直串联:
例如,如果使用 sum
函数作为变换函数,则中间结果是每个块之和。因此,结果是长度等于块数的一个向量,而不是针对元素之和返回单一标量值。
ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA'); ds.SelectedVariableNames = {'ArrDelay' 'DepDelay'}; tt = tall(ds); tX = tt.ArrDelay; f = @(x) sum(x,'omitnan'); s = matlab.tall.reduce(f, @(x) x, tX); s = gather(s)
s = 140467 101065 164355 135920 111182 186274 21321
版本历史记录
在 R2018b 中推出
MATLAB 命令
您点击的链接对应于以下 MATLAB 命令:
请在 MATLAB 命令行窗口中直接输入以执行命令。Web 浏览器不支持 MATLAB 命令。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)