matlab.tall.reduce

Уменьшите массивы путем применения алгоритма сокращения к блокам данных

Описание

пример

tA = matlab.tall.reduce(fcn,reducefcn,tX) применяет функцию fcn каждому блоку массива tX для генерации частичных результатов. Затем функция применяется reducefcn к вертикальной конкатенации частичных результатов неоднократно, пока она не имеет один конечный результат, tA.

пример

tA = matlab.tall.reduce(fcn,reducefcn,tX,tY,...) задает несколько массивов tX,tY,... которые являются входами в fcn. Одни и те же строки каждого массива обрабатываются fcn; для примера, fcn(tX(n:m,:),tY(n:m,:)). Входы с высотой единицы передаются на каждый вызов fcn. С помощью этого синтаксиса fcn должен вернуть один выход, и reducefcn должен принять один вход и вернуть один выход.

пример

[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 должна иметь одинаковую высоту.

пример

[tA,tB,...] = matlab.tall.reduce(___,'OutputsLike',{PA,PB,...}) указывает, что выходы tA,tB,... имеют те совпадающие типы данных, что и прототипные массивы PA,PB,..., соответственно. Можно использовать любой из комбинаций входных аргументов в предыдущих синтаксисах.

Примеры

свернуть все

Создайте длинная таблица, извлеките tall vector из таблица, а затем найдите общее количество элементов в вектор.

Создайте длинная таблица для airlinesmall.csv набор данных. Данные содержат информацию о времени прибытия и вылета американских рейсов. Извлечение ArrDelay переменная, которая является вектором задержек прибытия.

ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA');
ds.SelectedVariableNames = {'ArrDelay' 'DepDelay'};
tt = tall(ds);
tX = tt.ArrDelay;

Использование matlab.tall.reduce для подсчета общего количества не- NaN элементы в tall vector. Первая функция 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 1.5 sec
Evaluation completed in 1.7 sec
s = 123523

Создайте длинная таблица, извлечите два tall vector из таблицы, а затем вычислите среднее значение каждого вектора.

Создайте длинная таблица для airlinesmall.csv набор данных. Данные содержат информацию о времени прибытия и вылета американских рейсов. Извлечение 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.8 sec
Evaluation completed in 2.1 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.76 sec
Evaluation completed in 0.99 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

Составьте длинная таблица, затем вычислите среднюю задержку рейса для каждого года в данных.

Создайте длинная таблица для airlinesmall.csv набор данных. Данные содержат информацию о времени прибытия и вылета американских рейсов. Удалите строки недостающих данных из таблицы и извлеките ArrDelay, DepDelay, и Year переменные. Эти переменные являются векторами прибытия и задержек вылета и связанных лет для каждого рейса в наборе данных.

ds = tabularTextDatastore('airlinesmall.csv','TreatAsMissing','NA');
ds.SelectedVariableNames = {'ArrDelay' 'DepDelay' 'Year'};
tt = tall(ds);
tt = rmmissing(tt);

Использование matlab.tall.reduce применить две функции к длинная таблица. Первая функция объединяет 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 vectors. Поскольку входы (тип 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.1 sec
Evaluation completed in 1.3 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.48 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  
      ⋮

Вычислите взвешенное стандартное отклонение и дисперсию длинный массив с помощью вектора весов. Это один из примеров того, как можно использовать matlab.tall.reduce работать с функциями, которые длинные массивы еще не поддерживают.

Создайте два высоких вектора случайных данных. 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

Затем запишите функцию сокращения, которая действует на блоках высоких векторов, чтобы вычислить взвешенную дисперсию и стандартное отклонение.

type weightedStats.m
function [wvar, wstd] = weightedStats(X, P)
  wvar = var(X,P);
  wstd = std(X,P);
end

Использование matlab.tall.reduce применить эти функции к блокам данных в высоких векторах.

[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 должен быть того же типа, что и первый вход tX. Можно использовать 'OutputsLike' опция для возврата выходов различных типов данных. Если 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, ...] происходит от того же индекса в tall размерности, принимая, что длинный массив является nonsingleton в tall размерности. Для примера, если tX и tY nonsingleton в tall размерности, тогда первый набор блоков может быть x = tX(1:20000,:) и y = tY(1:20000,:).

    • Если первая размерность любого из [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. Пустые входы могут возникнуть, когда файл пуст или если вы сделали много фильтрации данных.

Для примера эта функция принимает два массива входа, квадраты и возвращает два выхода массива:

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 должен быть того же типа, что и первый вход tX. Можно использовать 'OutputsLike' опция для возврата выходов различных типов данных. Если 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. Пустые входы могут возникнуть, когда файл пуст или если вы сделали много фильтрации данных. Для этого вызова все входные блоки являются пустыми массивами правильного типа и размера в размерностях, выходящих за пределы первого.

Некоторые примеры подходящих функций сокращения являются встроенными функциями уменьшения размерности, такими как sum, prod, maxи так далее. Эти функции могут работать с промежуточными результатами, полученными fcn и возвращает один скаляр. Эти функции имеют свойства, которые не изменяют окончательный ответ в порядке, в котором происходят конкатенации, и в количестве раз, когда применяется операция сокращения. Некоторые функции, такие как mean и var, обычно следует избегать как функции сокращения, потому что количество раз, когда операция сокращения применяется, может изменить окончательный ответ.

Пример: tC = matlab.tall.reduce(@numel,@sum,tX) находит количество элементов в каждом блоке, а затем суммирует результаты, чтобы подсчитать общее количество элементов.

Типы данных: function_handle

Входные массивы, заданные как скаляры, векторы, матрицы или многомерные массивы. Входные массивы используются в качестве входов в функции преобразования fcn. Каждый входной массив tX,tY,... должны иметь совместимые высоты. Два входа имеют совместимую высоту, когда они имеют одинаковую высоту, или когда один вход имеет высоту 1.

Прототип выхода массивов, заданный как массивы. Когда вы задаете 'OutputsLike', выходные массивы tA,tB,... возвращено matlab.tall.reduce имеют те совпадающие типы данных и атрибуты, что и указанные массивы {PA,PB,...}.

Пример: tA = matlab.tall.reduce(fcn,reducefcn,tX,'OutputsLike',{int8(1)});, где tX - это длинный массив двойной точности, возвратов tA как int8 вместо double.

Выходные аргументы

свернуть все

Выходные массивы, возвращенные как скаляры, векторы, матрицы или многомерные массивы. Если какой-либо вход в matlab.tall.reduce tall, тогда все выходные аргументы также высокие. В противном случае все выходные аргументы являются массивами в памяти.

Размер и тип данных выходных массивов зависят от заданных функций fcn и reducefcn. В целом выходы tA,tB,... все должны иметь тот совпадающий тип данных, что и первый вход tX. Однако можно задать 'OutputsLike' для возврата различных типов данных. Массивы выхода tA,tB,... все имеют одинаковую высоту.

Подробнее о

свернуть все

Блоки Длинный массив

Когда вы создаете длинный массив из datastore, базовый datastore облегчает перемещение данных во время вычисления. Данные перемещаются дискретными частями, называемыми блоками или фрагментами, где каждый блок является набором последовательных строк, которые могут помещаться в памяти. Например, один блок 2-D массива (такого как таблица) X(n:m,:), для некоторых нижних индексов n и m. Размер каждого блока основан на значении ReadSize свойство datastore, но блок может быть не того размера. В целях matlab.tall.reduce, длинный массив рассматривается как вертикальная конкатенация многих таких блоков:

Для примера, если вы используете 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