MATLAB: вернуть оба аргумента из ISMEMBER при использовании внутри SPLITAPPLY

Как я могу получить доступ к обоим аргументам ismember, когда он используется внутри splitapply?

slitapply возвращает только скалярные значения для каждой группы, поэтому для вычисления нескалярных значений для каждой группы (как возвращается первым аргументом ismemebr) необходимо заключить анонимную функцию (в данном случае ismember) в фигурные скобки {}, чтобы вернуть массив ячеек.

Но теперь, когда я предоставляю два выходных аргумента splitapply, я получаю сообщение об ошибке:

Output argument "varargout{2}" (and maybe others) not assigned during call to "@(x,y) {ismember(x,y)}"

ДОБАВИТЬ 1

Я могу создать другую функцию, скажем, ismember2cell, которая будет применять ismember и превращать выходные данные в массивы ячеек:

function [a, b] = ismember2cell(x,y)
  [a,b] = ismember(x,y);
  a = {a};
  b = {b};
end

но, возможно, есть решение, которое не требует этого обходного пути.


person Confounded    schedule 06.11.2017    source источник


Ответы (2)


Один потенциально более быстрый вариант — просто сделать то, что splitapply уже делает под капот, разделив ваши данные на массивы ячеек (используя такие функции, как mat2cell или accumarray), а затем с помощью cellfun, чтобы применить к ним вашу функцию. Использование cellfun позволит вам легко получать несколько выходных данных (например, из ismember). Например:

% Sample data:
A = [1 2 3 4 5];
B = [1 2 1 5 5];
G = [1 1 1 2 2];  % Group index

% Group data into cell arrays:
cellA = accumarray(G(:), A(:), [], @(x) {x(:).'});  % See note below about (:).' syntax
cellB = accumarray(G(:), B(:), [], @(x) {x(:).'});

% Apply function:
[Lia, Locb] = cellfun(@ismember, cellA, cellB, 'UniformOutput', false);

ПРИМЕЧАНИЕ. Мои образцы данных представляют собой векторы-строки, но мне пришлось использовать оператор двоеточия, чтобы преобразовать их в векторы-столбцы при передаче их в accumarray (ему нужны столбцы). После распределения в массив ячеек каждая часть вектора по-прежнему будет вектором-столбцом, и я просто хотел сохранить их как векторы-строки, чтобы они соответствовали исходным данным выборки. Синтаксис (:).' представляет собой изменение формы двоеточия, за которым следует несопряженное транспонирование, гарантирующее вектор-строка в результате независимо от формы x. В этом случае я, вероятно, мог бы просто использовать .', но у меня есть привычка никогда не предполагать, какова форма переменной.

person gnovice    schedule 06.11.2017
comment
Спасибо. Это выглядит интересно. Проверим и вернемся. - person Confounded; 06.11.2017
comment
Не могли бы вы объяснить / указать на объяснение синтаксиса, используемого при создании массивов ячеек x(:).'? В частности, что делает точка .? Спасибо - person Confounded; 06.11.2017
comment
@Confounded: я добавил к ответу дополнительное примечание. Надеюсь, это проясняет, что я делал. - person gnovice; 06.11.2017

Я не могу найти глобальное решение, но принятый ответ этот пост помогает мне определить вспомогательную функцию для вашей проблемы:

function varargout = out2cell(varargin)
[x{1:nargout}]=feval(varargin{:});
varargout = num2cell(x);

Я думаю, что у вас может получиться позвонить

splitapply(@(x,y) out2cell(@ismember, x, y), A, B);
person Bentoy13    schedule 06.11.2017