主要内容

开发自定义高阵列算法

高数组是一种使用传统MATLAB处理大型数据集的强大而直观的方法®语法。但是,由于高数组操作的是数据块,而每个数据块都单独装入内存,因此大多数函数的传统算法都需要更新,以使用并行方法来支持高数组。金宝app本主题向您展示如何开发自己的并行算法来操作高数组。

目前可用的自定义函数应用到高数组的方法有:

无论您选择哪种操作,都有适用于所有方法的选项、性能考虑因素和常见问题。

实现自定义算法的原因

大多数常见的数学函数和MATLAB操作已经支持高数组。金宝app如果已经支持该功能,那么可能不需要编写自己的算法。金宝app

下面是一些你可能想要为高数组实现自定义算法的原因:

  • 实现当前不支持的函数金宝app如果一个特定的函数目前不支持高数组,那么你可以使用这里列出的api编写一个支持高数组的函数版金宝app本。

  • 利用现有代码—如果您有对内存中的数据执行一些操作的现有代码,那么只需稍加修改,就可以使其与高数组操作兼容。这种方法避免了将代码转换为适合支持高数组的MATLAB语言子集的需要。金宝app

  • 获得性能-例如,可以将MATLAB函数重写为c++ MEX函数,然后可以使用这里概述的api调用MEX函数对数据进行操作。

  • 使用首选的外部库-为了组织内部的兼容性,有时需要使用特定的外部库来进行某些计算。您可以使用这里概述的api使用这些外部库重新实现函数。

金宝app支持api

所支持的金宝appapi用于高级使用,不包括广泛的输入检查。预计将花费一些时间测试您实现的补充函数是否满足所有需求并执行您期望的计算。这里列出了当前支持的金宝app用于编写高数组算法的api。

功能名称 描述
matlab.tall.transform 对一个或多个tall数组的每个块应用指定的函数。
matlab.tall.reduce 对一个或多个tall数组的每个块应用指定的函数。然后将该函数的输出输入第二个约简函数。
matlab.tall.movingWindow 对数据块应用移动窗口函数。
matlab.tall.blockMovingWindow

应用移动窗口函数和块减少填充块的数据。

背景:高阵列块

从数据存储创建高数组时,底层数据存储有助于在计算期间移动数据。数据以离散块的形式移动,称为,其中每个块是一组连续的行,可以放入内存中。例如,一个2-D数组(如表)的一个块为X (n: m:)。的值为基础ReadSize属性,但块并不总是准确的大小。为了开发高阵列算法,高阵列被认为是许多这样的块的垂直连接。

给定数组的块是在运行时基于可用内存选择的,因此它们可以是动态的。因此,这些块可能不是完全运行之间的大小相同。如果计算机上有影响可用内存的更改,则会影响块的大小。

虽然本页仅指而且在二维意义上,这些概念扩展到N-D高数组。块的大小只在第一个维度上受到限制,因此块包含其他维度的所有元素;例如,X (n: m,:,:,…)。而且,N-D数组不是行X (p::,…)

单步变换操作

matlab.tall.transformFunction对tall数组的每个块应用一个函数,因此您可以使用它来应用按块的转换、过滤或数据缩减。例如,您可以删除具有特定值的行,将数据居中并缩放,或者检测某些条件并转换特定的数据块。这些图形显示了当数组中的块被操作时发生了什么matlab.tall.transform

操作

描述

例子

转换—每个块的行数保持不变,但数值有所变化。

  • A = matlab.tall。变换(@sin tX)计算每个块中元素的正弦值。

  • A = matlab.tall.transform(@(X) X ^2, tX)对每个块中的元素进行平方。

过滤-每个块中的行数减少,因此新数组中的块可能包括原本存在于其他块中的行。

  • A = matlab.tall.transform(@(X) topkrows(X,5), tX)只从每个块中提取前5行,过滤掉其他行。

  • A = matlab.tall。变换(@sum tX)计算每个块中元素的和,这将每个块简化为一个标量。元素的数量一个等于块的数量。

转换语法

应用单步转换的通用语法是

[tA, tB, tC,…]= matlab.tall.transform(fcn, tX, tY, tZ, ...)

功能需求fcn

的一般功能签名fcn

[a, b, c,…]= fcn(x, y, z, ...)
fcn必须满足这些要求:

  1. 输入参数-输入[x, y, z,…]是适合内存的数据块。这些块是通过从相应的高数组输入中提取数据来生成的[tX, tY, tZ,…]。输入[x, y, z,…]满足以下属性:

    • 所有的[x, y, z,…]在任何允许的扩展后,在第一个维度中具有相同的大小。

    • 数据块[x, y, z,…]来自高维度中的相同索引,假设高数组在高维度中是非单例的。例如,如果tX而且在高维度是非单块的,那么第一组块可能是x = tX(1:2000,:)而且y = tY(1:2000,:)

    • 如果任何一个的第一个维度[tX, tY, tZ,…]大小为1,则对应的块[x, y, z,…]由高数组中的所有数据组成。

  2. 输出参数-输出[a, b, c,…]是块,适合在内存中,被发送到各自的输出[tA, tB, tC,…]。输出[a, b, c,…]满足以下属性:

    • 所有的[a, b, c,…]必须在第一维度中有相同的大小。

    • 所有的[a, b, c,…]是否垂直连接到之前调用的各自结果fcn

    • 所有的[a, b, c,…]发送到各自目标输出数组中第一个维度中的相同索引。

  3. 功能规则- - - - - -fcn必须满足函数规则:

    • F ([inputs1;inputs2) == [F(inputs1);F (inputs2)):将函数应用于输入的连接应该与将函数分别应用于输入,然后将结果连接相同。

  4. 空输入-确保fcn可以处理高度为0的输入。当文件为空或对数据进行了大量过滤时,可能会出现空输入。

两步还原操作

matlab.tall.reduce将两个函数应用到一个tall数组,第一步的结果作为输入输入到最后的简化步骤。将约简函数反复应用于中间结果,直到获得适合内存的单个最终块。在MapReduce范式中,这个过程类似于“单键”MapReduce操作,中间结果都具有相同的键,并在约简步骤中进行组合。

第一步类似于matlab.tall.transform并有相同的要求。但是,减少步骤总是将中间结果减少到一个适合内存的块。这些图形显示了当数组中的块被操作时发生了什么matlab.tall.reduce

操作

描述

例子

改造+减法—在第一步之后,每个块的行数保持不变,然后中间结果减少到一个块。

  • A = matlab.tall.reduce(@sin,@max,tX)计算每个值块的正弦值,然后在约简步骤中找到总体最大值。

  • A = matlab.tall.reduce(@(X) X ^2, @mean, tX)对每个块中的元素进行平方,然后在约简步骤中计算总体平均值。

过滤+约简—第一步减少每个块的行数。然后中间结果被减少到一个块。

  • A = matlab.tall。reduce(@sum, @sum, tX)计算每个块中元素的和,然后在约简步骤中找到元素的总和。

  • A = matlab.tall.reduce(@(X) X(X>0), @mean, tX)过滤掉所有的负值,然后计算出剩余值的总体平均值。

减少语法

应用两步简化的通用语法是

[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, ...)

也就是说,输入tall数组[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必须满足这些要求:

  1. 输入参数-输入[a, b, c,…]是适合内存的块。数据块是返回的输出fcn,或部分减少输出reducefcn现在正在进行进一步的手术。输入[a, b, c,…]满足以下属性:

    • 输入[a, b, c,…]在第一维中有相同的尺寸。

    • 对于第一维中给定的索引,表示数据块的每一行[a, b, c,…]要么来自于输入,要么来自于之前对的相同调用reducefcn

    • 对于第一维中给定的下标,每一行的输入[a, b, c,…]因为该索引起源于第一维中的相同索引。

  2. 输出参数-所有输出[rA, rB, rC,…]必须在第一维度中有相同的大小。此外,它们必须与各自的输入垂直连接[a, b, c,…]允许在必要时重复削减。

  3. 功能规则- - - - - -reducefcn必须满足这些函数规则(直到舍入错误):

    • F(input) == F(F(input)):对相同的输入重复应用该函数不会改变结果。

    • F ([input1;input2) == F([input2;input1]):结果不应取决于串联的顺序。

    • F ([input1;input2) == F([F(input1);F (input2)]):将函数应用于某些中间结果的拼接一次应该与分别应用它、拼接并再次应用它相同。

  4. 空输入-确保reducefcn可以处理高度为0的输入。当文件为空或对数据进行了大量过滤时,可能会出现空输入。对于这个调用,所有输入块都是正确类型和大小的空数组,维度大于第一个。

滑动窗口的操作

matlab.tall.movingWindow而且matlab.tall.blockMovingWindow函数将一个函数应用到高数组中的数据的Windows。而matlab.tall.transform而且matlab.tall.reduce移动窗口函数一次对整个数据块进行操作,当一个窗口从数组的开头移动到末尾时,移动窗口函数对数据的窗口进行操作。窗口可以跨越从磁盘读取的数据块。

这些图形显示了当数组中的块被操作时发生了什么matlab.tall.movingWindowmatlab.tall.blockMovingWindow

操作 描述 例子

窗口的转换—每个块的行数保持不变,但数值有所变化。输出包含对数据的不完整窗口和完整窗口执行的操作结果。

这两个matlab.tall.movingWindow而且matlab.tall.blockMovingWindow转换数据时“端点”是否默认为“缩水”,或者当指定填充值时。这两个值确保输出在第一个维度上的大小与输入相同。

  • A = matlab.tall。movingWindow(@mean, 100, tX)使用窗口大小为100计算移动平均值。

窗口的过滤—不完整的数据窗口将被丢弃,因此输出的元素比输入的元素少。输出只包含在完整的数据窗口上执行的操作结果。

这两个matlab.tall.movingWindow而且matlab.tall.blockMovingWindow删除不完整的窗口数据时“端点”“丢弃”

  • A = matlab.tall。movingWindow(@mean, 100, tX, 'EndPoints', 'discard')使用窗口大小为100,计算完整窗口数据的移动平均值。

你可以使用matlab.tall.movingWindow而且matlab.tall.blockMovingWindow对数据应用窗口转换或筛选器。例如,您可以计算跟踪平均值或移动中位数,或者您可以一次对同一个窗口应用多个操作。这两种功能在以下方面有所不同:

  • matlab.tall.movingWindow适用于fcn对所有Windows的数据,无论Windows是否完整。matlab.tall.blockMovingWindow适用于windowfcn对不完整的窗口数据,并适用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是一个包含字段的结构窗口而且。当你写函数的时候。使用这些字段在每个块中挑选出数据的窗口。

一般规则的大纲fcnwindowfcn,blockfcn必须遵循,看到fcn功能需求。除了信息输入,fcn而且windowfcn有相同的要求。但是,要求为blockfcn是不同的,因为该函数操作的是整个数据块。

功能需求windowfcn

的一般功能签名windowfcn

[a, b, c,…]= windowfcn(info, x, y, ...)
信息Input是由提供的结构matlab.tall.blockMovingWindow其中包括以下字段:

  • —指定窗口之间的步长(默认为1)“步”名称-值对。

  • 窗口—指定窗口大小。属性设置此值窗口输入参数。

windowfcn必须满足这些要求:

  1. 输入参数-输入[x, y, z,…]是适合内存的数据块。这些块是通过从相应的高数组输入中提取数据来生成的[tX, tY, tZ,…]。输入[x, y, z,…]满足以下属性:

    • 所有的输入[x, y, z,…]在第一维中有相同的尺寸。

    • 数据块[x, y, z,…]来自高维度中的相同索引,假设高数组在高维度中是非单例的。例如,如果tX而且在高维度是非单块的,那么第一组块可能是x = tX(1:2000,:)而且y = tY(1:2000,:)

    • 当任何一个的第一维度[tX, tY, tZ,…]大小为1,对应的块[x, y, z,…]由高数组中的所有数据组成。

    • 应用windowfcn必须导致将输入数据缩减为高度为1的标量或数组的切片。

      当输入是矩阵、N-D数组、表格或时间表时,应用windowfcn必须导致在其每个列或变量中减少输入数据。

  2. 输出参数-输出[a, b, c,…]适合内存的块是否被发送到各自的输出[tA, tB, tC,…]。输出[a, b, c,…]满足以下属性:

    • 所有的输出[a, b, c,…]必须在第一维度中有相同的大小。

    • 所有的输出[a, b, c,…]是否垂直连接到之前调用的各自结果windowfcn

    • 所有的输出[a, b, c,…]发送到各自目标输出数组中第一个维度中的相同索引。

  3. 功能规则- - - - - -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不必为不完整的数据窗口定义行为。

  • 第一个数据窗口从块的第一个元素开始。最后一个窗口的最后一个元素是块的最后一个元素。

blockfcn必须满足这些要求:

  1. 输入参数-输入[bX, bY, bZ,…]是适合内存的数据块。这些块是通过从相应的高数组输入中提取数据来生成的[tX, tY, tZ,…]。输入[bX, bY, bZ,…]满足以下属性:

    • 所有的输入[bX, bY, bZ,…]在任何允许的扩展后,在第一个维度中具有相同的大小。

    • 数据块[bX, bY, bZ,…]来自高维度中的相同索引,假设高数组在高维度中是非单例的。例如,如果tX而且在高维度是非单块的,那么第一组块可能是bX = tX(1:2000,:)而且bY = tY(1:20000,:)

    • 如果是任何数据输入的第一个维度[tX, tY, tZ,…]大小为1,则对应的块[bX, bY, bZ,…]由高数组中的所有数据组成。

    • 应用blockfcn必须导致输入数据的减少,使结果的高度等于块中的窗口数。你可以使用信息。窗口而且信息。步确定块中窗口的数量。

      如果输入是矩阵、N-D数组、表格或时间表,则应用blockfcn必须导致在其每个列或变量中减少输入数据。

  2. 输出参数-输出[a, b, c,…]是块,适合在内存中,被发送到各自的输出[tA, tB, tC,…]。输出[a, b, c,…]满足以下属性:

    • 所有的输出[a, b, c,…]必须在第一维度中有相同的大小。

    • 所有的输出[a, b, c,…]是否垂直连接到之前调用的各自结果blockfcn

    • 所有的输出[a, b, c,…]发送到各自目标输出数组中第一个维度中的相同索引。

  3. 功能规则- - - - - -blockfcn必须满足这个函数规则:

    • F ([inputs1;inputs2) == [F(inputs1);F (inputs2)):将函数应用于输入的连接应该与将函数分别应用于输入,然后将结果连接相同。

控制输出数据类型

如果最终输出的是任意一个金宝app支持api有不同的数据类型从输入,那么你必须指定“OutputsLike”名称-值对提供一个或多个原型数组,这些原型数组具有与相应输出相同的数据类型和属性。的价值“OutputsLike”始终是单元格数组,每个单元格包含对应输出参数的原型数组。

例如,调用matlab.tall.transform接受一个高数组tX作为输入,并返回两个由原型数组指定的不同类型的输出protoA而且protoB。输出一个具有相同的数据类型和属性protoA,同样地B而且protoB

C = {protoA protoB};[A, B] = matlab.tall。transform(fcn, tX, 'OutputsLike', C)

提供原型数组的常用方法是调用fcn使用适当数据类型的普通输入,因为由返回的输出fcn拥有正确的数据类型。在本例中,transform函数接受一个高double,但返回一个高表。通过调用生成原型数组fcn (0)并且原型被指定为的值“OutputsLike”

ds = tabularTextDatastore(' airlinsmall .csv','TreatAsMissing','NA');ds。SelectedVariableNames = {'ArrDelay', 'DepDelay'};Tt =高(ds);tX = tt.ArrDelay;fcn = @(x) table(x,'VariableNames',{'MyVar'});proto_A = fcn(0);A = matlab.tall.transform(fcn,tX,'OutputsLike',{proto_A});

编码和性能技巧

  • 将所有分析放在一个函数中,调用该函数直接对数据进行操作,而不是使用不必要的嵌套函数。

  • 用一小部分数据进行实验。在扩展到整个数据集之前,分析您的代码以找到并修复瓶颈,在整个数据集中,瓶颈可能会被极大地放大。

  • 注意数据的方向,因为一些函数根据输入数据以不同的形状返回输出。例如,独特的可以返回行向量或列向量,具体取决于输入数据的方向。

  • 块在运行时基于可用的计算机内存动态生成。确保任何指定的约简函数都遵守函数规则F ([input1;input2) == F([F(input1);F (input2)])。如果不遵守这一规则,那么两次试验的结果可能会有显著差异。

  • 块在第一个维度中可以有任何大小,包括0或1。大小0或1可以在中间计算中出现,这是过滤或约简操作的结果。确保你的函数在这两种情况下都做正确的事情。函数没有正确处理这些情况的一个迹象是,当您收到“输出大小不同”错误消息时。

另请参阅

|||

相关的话题