4

如何访问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

但也许有一个不需要这种解决方法的解决方案。

4

2 回答 2

3

一种可能更快的选择是splitapply通过将数据拆分为单元数组(使用类似mat2cellor之类的函数accumarray)然后cellfun在它们之间应用您的函数来完成已经在幕后所做的事情。使用cellfun将允许您轻松捕获多个输出(例如 from 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. 在这种情况下,我可能只使用.',但我已经养成了从不假设变量的形状是什么的习惯。

于 2017-11-06T16:01:49.627 回答
0

我找不到全局解决方案,但这篇文章的公认答案可以帮助我为您的问题定义一个辅助函数:

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

我想你可能会成功打电话

splitapply(@(x,y) out2cell(@ismember, x, y), A, B);
于 2017-11-06T13:48:26.360 回答