开发自定义高数组算法
高数组是使用传统MATLAB处理大型数据集的一种强大而直观的方法®语法。然而,由于高数组操作的是数据块,每个数据块都可以单独放入内存中,因此大多数函数的传统算法都需要更新,以使用并行的方法来支持高数组。本主题向您展示如何开发自己的并行算法来操作高数组。
目前可用的将自定义函数应用到高数组的方法有:
无论您选择哪种操作,都有适用于所有方法的选项、性能考虑因素和常见问题。
实现自定义算法的原因
大多数常见的数学函数和MATLAB操作已经支持高数组。如果功能已经得到支持,那么可能就没有必要编写自己的算法了。
以下是为什么你可能想要为高数组实现自定义算法的一些原因:
实现当前不支持的函数-如果一个特定的函数目前不支持高数组,那么你可以使用这里列出的api来编写一个支持高数组的函数版本。
利用现有的代码-如果你有对内存中数据执行一些操作的现有代码,那么只需要稍加修改,你就可以使它与对高数组的操作兼容。这种方法避免了转换代码以适应支持高数组的MATLAB语言子集的需要。
获得性能-例如,您可以将MATLAB函数重写为c++ MEX函数,然后可以使用这里概述的api调用MEX函数对数据进行操作。
使用首选外部库-为了在组织内部兼容,有时需要使用特定的外部库进行某些计算。您可以使用这里概述的api使用这些外部库重新实现函数。
支持api
受支持的api是用于高级使用的,不包括大量的输入检查。预计将花费一些时间测试所实现的补充功能是否满足所有需求并执行预期的计算。这里列出了当前支持的用于编写高数组算法的api。
包函数名 | 描述 |
---|---|
matlab.tall.transform |
对一个或多个高数组的每个块应用指定的函数。 |
matlab.tall.reduce |
对一个或多个高数组的每个块应用指定的函数。然后将该函数的输出输入第二个约简函数。 |
matlab.tall.movingWindow |
对数据块应用移动窗口函数。 |
matlab.tall.blockMovingWindow |
对填充的数据块应用移动窗口函数和块减少。 |
背景:高阵列块
当从数据存储中创建高数组时,底层数据存储有助于在计算期间移动数据。数据以离散的形式移动,称为块,其中每个块是一组连续的行,可以装入内存中。例如,一个2-D数组(如表)的一个块X (n: m:)
.的值为每个块的大小ReadSize
属性,但块的大小并不总是那么精确。为了开发高数组算法,高数组被认为是许多这样的块的垂直连接。
给定数组的块是在运行时根据可用内存选择的,因此它们可以是动态的。因此,这些块可能不是完全运行之间的大小相同。如果您的计算机上有影响可用内存的更改,那么就会影响块的大小。
虽然此页仅指块而且行在二维的意义上,这些概念扩展到N-D高数组。块的大小只限制在第一个维度,所以块包含其他维度中的所有元素;例如,X (n: m,:,:,…)
.而且,与行不同,N-D数组具有片如X (p::,…)
.
单步执行转换操作
的matlab.tall.transform
函数将单个函数应用到高数组的每个块,因此可以使用它应用按块的转换、过滤或数据缩减。例如,您可以删除具有特定值的行,将数据居中并缩放,或者检测某些条件并转换特定的数据片段。这些图显示了数组中的块在被操作时发生了什么matlab.tall.transform
.
操作 |
描述 | 例子 |
---|---|---|
|
转换—每个块的行数保持不变,但值会发生变化。 |
|
|
过滤-每个块中的行数减少,所以新数组中的块可能包括原来存在于其他块中的行。 |
|
转换语法
应用单步转换的通用语法是
[tA, tB, tC,…]= matlab.tall.transform(fcn, tX, tY, tZ, ...)
功能要求fcn
的一般功能签名fcn
是
[a, b, c,…]= fcn(x, y, z, ...)
fcn
必须满足以下要求:
输入参数——输入
[x, y, z,…]
是存储在内存中的数据块。这些块是通过从各自的高数组输入中提取数据而产生的[tX, tY, tZ,…]
.输入[x, y, z,…]
满足这些属性:所有的
[x, y, z,…]
在任何允许的扩展后,在第一个维度中具有相同的大小。的数据块
[x, y, z,…]
来自高维度中的相同索引,假设高数组在高维度中是非单例的。例如,如果tX
而且泰
在高维中是非单的,那么第一组块可能是x = tX (1:20000:)
而且y =泰(1:20000:)
.如果第一个维度
[tX, tY, tZ,…]
大小为1
,则对应的块[x, y, z,…]
由该高数组中的所有数据组成。
输出参数——输出
[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的输入。当文件为空或对数据进行了大量过滤时,可能会出现空输入。
两步还原操作
matlab.tall.reduce
将两个函数应用到一个高数组中,第一步的结果作为最后一步的输入输入。对中间结果重复应用约简函数,直到获得一个适合内存的最终块。在MapReduce范式中,这个过程类似于“单键”MapReduce操作,中间结果都具有相同的键,并在还原步骤中进行组合。
第一步类似于matlab.tall.transform
有相同的要求。然而,简化步骤总是将中间结果简化为一个适合内存的块。这些图显示了数组中的块在被操作时发生了什么matlab.tall.reduce
.
操作 |
描述 | 例子 |
---|---|---|
|
减少转换+-在第一步之后每个block的行数保持不变,然后中间结果减少到一个block。 |
|
|
减少过滤+-在第一步中,每个块中的行数减少。然后中间结果被简化为一个块。 |
|
减少语法
应用两步简化的通用语法是
[rA, rB, rC,…]= matlab.tall.reduce(fcn, reducefcn, tX, tY, tZ, ...)
的功能签名fcn
是
[a, b, c,…]= fcn(x, y, z, ...)
的功能签名reducefcn
是
[rA, rB, rC,…]= reducefcn(a, b, c, ...)
也就是输入的高数组[tX, tY, tZ,…]
被分成块[x, y, z,…]
这些都是fcn
.然后,fcn
返回输出[a, b, c,…]
这些都是reducefcn
.最后,reducefcn
返回最终结果。(rA, rB, rC)
由matlab.tall.reduce
.
功能要求reducefcn
的要求fcn
是否与书中概述的相同fcn的功能要求.但是,要求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 (F(输入))
:对相同的输入重复应用该函数不会改变结果。F ([input1;input2]) = = F ([input2;input1])
:结果不应取决于连接的顺序。F ([input1;input2]) = = F ([F (input1);F (input2)])
:将函数一次应用到一些中间结果的拼接上,应该与分别应用它,拼接,然后再次应用是一样的。
空输入——确保
reducefcn
可以处理高度为0的输入。当文件为空或对数据进行了大量过滤时,可能会出现空输入。对于此调用,所有输入块都是正确类型和大小的空数组,维度超过第一个。
滑动窗口的操作
的matlab.tall.movingWindow
而且matlab.tall.blockMovingWindow
函数将函数应用到高数组中的数据窗口。而matlab.tall.transform
而且matlab.tall.reduce
移动窗口函数一次操作整个数据块,当窗口从数组的开始移动到结束时,移动窗口函数对数据的窗口进行操作。窗口可以在从磁盘读取的数据块之间跨越。
这些图显示了数组中的块在被操作时发生了什么matlab.tall.movingWindow
或matlab.tall.blockMovingWindow
.
操作 | 描述 | 例子 |
---|---|---|
|
窗口的转换—每个块的行数保持不变,但值会发生变化。输出包含对数据的不完整和完整窗口执行的操作的结果。 这两个 |
|
|
窗口的过滤-不完整的数据窗口将被丢弃,因此输出的元素比输入的元素少。输出只包含在完整的数据窗口上执行的操作的结果。 这两个 |
|
您可以使用matlab.tall.movingWindow
而且matlab.tall.blockMovingWindow
对数据应用窗口转换或过滤器。例如,您可以计算跟踪平均值或移动中位数,或者您可以对同一个窗口一次应用多个操作。这两个功能在以下方面有所不同:
matlab.tall.movingWindow
适用于fcn
对所有Windows的数据,无论该Windows是否完整。matlab.tall.blockMovingWindow
适用于windowfcn
到不完整的Windows数据,并应用blockfcn
完成Windows的数据。matlab.tall.movingWindow
一次操作单个数据窗口。matlab.tall.blockMovingWindow
操作包含多个完整窗口的整个数据块,这减少了计算中所需的函数调用的数量。
移动窗口语法
将移动窗口操作应用到单个数据窗口的语法是
[tA, tB, tC,…]= matlab.tall.movingWindow(fcn, window, tX, tY, tZ, ...)
的功能签名fcn
必须
[a, b, c,…]= fcn(x, y, z, ...)
类似地,对整个数据块应用移动窗口操作的语法是
[tA, tB, tC,…]= matlab.tall.blockMovingWindow(windowfcn, blockfcn, window, tX, tY, tZ, ...)
的功能特征windowfcn
而且blockfcn
必须
[a, b, c,…]= windowfcn(info, x, y, z, ...) [a, b, c, ...] = blockfcn(info, bX, bY, bZ, ...)
的信息
Input是一个包含字段的结构窗口
而且步
.当你写函数的时候。使用这些字段可以在每个块中挑选出数据的Windows。
对于一般规则的概述fcn
,windowfcn
,blockfcn
必须遵循,看fcn的功能要求.除了信息
输入,fcn
而且windowfcn
有相同的要求。但是,要求blockfcn
是不同的,因为该函数操作整个数据块。
功能要求windowfcn
的一般功能签名windowfcn
是
[a, b, c,…]= windowfcn(info, x, y, ...)
信息
Input是由提供的结构matlab.tall.blockMovingWindow
其中包括以下字段:
步
—指定窗口之间的步长(默认为1)“步”
名称-值对。窗口
-指定窗口大小。方法设置此值窗口
输入参数。
windowfcn
必须满足以下要求:
输入参数——输入
[x, y, z,…]
是存储在内存中的数据块。这些块是通过从各自的高数组输入中提取数据而产生的[tX, tY, tZ,…]
.输入[x, y, z,…]
满足这些属性:所有的输入
[x, y, z,…]
在第一个维度有相同的尺寸。的数据块
[x, y, z,…]
来自高维度中的相同索引,假设高数组在高维度中是非单例的。例如,如果tX
而且泰
在高维中是非单的,那么第一组块可能是x = tX (1:20000:)
而且y =泰(1:20000:)
.当任何的第一个维度
[tX, tY, tZ,…]
大小为1
,对应的块[x, y, z,…]
由该高数组中的所有数据组成。应用
windowfcn
必须导致将输入数据简化为高度为1的数组的标量或片。当输入是矩阵、N-D数组、表或时间表时,应用
windowfcn
必须导致在其每列或变量中减少输入数据。
输出参数——输出
[a, b, c,…]
适合内存的块被发送到各自的输出吗[tA, tB, tC,…]
.输出[a, b, c,…]
满足这些属性:所有的输出
[a, b, c,…]
在第一个维度必须有相同的尺寸。所有的输出
[a, b, c,…]
是否与前一次调用的各自结果垂直连接windowfcn
.所有的输出
[a, b, c,…]
都发送到各自目标输出数组中第一个维度中的相同索引。
功能规则- - - - - -
windowfcn
必须满足以下功能规则:F ([inputs1;inputs2]) = = (F (inputs1);F (inputs2))
:将函数应用于输入的拼接,应该与将函数分别应用于输入,然后将结果拼接相同。
功能要求blockfcn
的一般功能签名blockfcn
是
[a, b, c,…]= blockfcn(info, bX, bY, bZ, ...)
信息
Input是由提供的结构matlab.tall.blockMovingWindow
其中包括以下字段:
步
—指定窗口之间的步长(默认为1)“步”
名称-值对。窗口
-指定窗口大小。方法设置此值窗口
输入参数。
数据块bX, bY, bZ,…
那matlab.tall.blockMovingWindow
提供给blockfcn
这些属性:
这些块只包含全尺寸的窗口。
blockfcn
不需要为不完整的Windows数据定义行为。第一个数据窗口从块的第一个元素开始。最后一个窗口的最后一个元素是块的最后一个元素。
blockfcn
必须满足以下要求:
输入参数——输入
[bX, bY, bZ,…]
是存储在内存中的数据块。这些块是通过从各自的高数组输入中提取数据而产生的[tX, tY, tZ,…]
.输入[bX, bY, bZ,…]
满足这些属性:所有的输入
[bX, bY, bZ,…]
在任何允许的扩展后,在第一个维度中具有相同的大小。的数据块
[bX, bY, bZ,…]
来自高维度中的相同索引,假设高数组在高维度中是非单例的。例如,如果tX
而且泰
在高维中是非单的,那么第一组块可能是bX = tX (1:20000:)
而且通过=泰(1:20000:)
.如果任何数据输入的第一个维度
[tX, tY, tZ,…]
大小为1
,则对应的块[bX, bY, bZ,…]
由该高数组中的所有数据组成。应用
blockfcn
必须导致输入数据的减少,使结果的高度等于块中的窗口数量。您可以使用信息。窗口
而且信息。步
来确定块中窗口的数量。如果输入是矩阵、N-D数组、表或时间表,则应用
blockfcn
必须导致在其每列或变量中减少输入数据。
输出参数——输出
[a, b, c,…]
是否块适合内存,发送到各自的输出[tA, tB, tC,…]
.输出[a, b, c,…]
满足这些属性:所有的输出
[a, b, c,…]
在第一个维度必须有相同的尺寸。所有的输出
[a, b, c,…]
是否与前一次调用的各自结果垂直连接blockfcn
.所有的输出
[a, b, c,…]
都发送到各自目标输出数组中第一个维度中的相同索引。
功能规则- - - - - -
blockfcn
必须满足以下功能规则:F ([inputs1;inputs2]) = = (F (inputs1);F (inputs2))
:将函数应用于输入的拼接,应该与将函数分别应用于输入,然后将结果拼接相同。
控件输出数据类型
如果最终输出的任何支持api与输入的数据类型不同,那么您呢必须指定“OutputsLike”
名称-值对,以提供一个或多个与相应输出具有相同数据类型和属性的原型数组。的价值“OutputsLike”
总是一个单元格数组,每个单元格包含对应输出参数的原型数组。
例如,这个调用matlab.tall.transform
接受一个高数组tX
作为输入,并返回由原型数组指定的不同类型的两个输出protoA
而且protoB
.输出一个
具有与?相同的数据类型和属性protoA
,同样地B
而且protoB
.
C = {protoA protoB};[A, B] = matlab.高。转换(fcn, tX, 'OutputsLike', C)
提供原型数组的常用方法是调用fcn
具有适当数据类型的普通输入,因为返回的输出fcn
有正确的数据类型。在本例中,transform函数接受一个高双精度表,但返回一个高表。通过调用生成一个原型数组fcn (0)
原型被指定为的值“OutputsLike”
.
ds = tabularTextDatastore(“airlinesmall.csv”、“TreatAsMissing”、“NA”);ds。SelectedVariableNames = {'ArrDelay', 'DepDelay'};tt =高(ds);tX = tt.ArrDelay;fcn = @(x)表(x,'变量名',{'MyVar'});proto_A = fcn (0);= matlab.tall.transform (fcn tX, OutputsLike, {proto_A});
编码和性能技巧
将所有分析放在一个函数中,调用该函数直接对数据进行操作,而不是使用不必要的嵌套函数。
使用一小部分数据进行实验。对代码进行分析,在扩展到整个数据集之前找到并修复瓶颈,在整个数据集中,瓶颈可能会被极大地放大。
注意数据的方向,因为一些函数根据输入数据以不同的形状返回输出。例如,
独特的
可根据输入数据的方向返回行向量或列向量。块在运行时根据可用的计算机内存动态生成。确保任何指定的约简函数都遵守函数规则
F ([input1;input2]) = = F ([F (input1);F (input2)])
.如果不遵守这一规则,那么不同试验之间的结果会有显著差异。块在第一个维度中可以有任何大小,包括0或1。大小0或1可能在中间计算中出现,这是过滤或约简操作的结果。确保你的函数在这两种情况下都做了正确的事情。函数不能正确处理这些情况的一个标志是,当您收到“Output is different size”错误消息时。
另请参阅
matlab.tall.reduce
|matlab.tall.transform
|matlab.tall.movingWindow
|matlab.tall.blockMovingWindow