对非数值数据使用' bsxfun '



对于非数值数据是否有与bsxfun等价的?

例如,我想比较存储在两个单元格数组中的所有字符串对:

>> a = {'aa', 'bb', 'cc'};
>> b = {'dd', 'aa'};
>> bsxfun( @strcmp, a, b' ); % not working for cells :-(

我喜欢Rody的解决方案,但是您也可以这样做:

ia=(1:length(a)).'; ib=1:length(b);
a=a(:);
bsxfun(@(ii,jj) strcmp(  a(ii),b(jj) )  ,ia, ib);

恐怕没有这样的等效单元格数组:-(

)

在我看来,你可以:

  1. 遵循Oleg的建议并使用循环
  2. 使用现有的实现,如mAryCellFcn csxfun 从文件交换
  3. 滚动您自己的函数。例如,下面是Robert想法的一个变体,它适用于任何维度的输入(当然是在bsxfun的限制下)和任意二进制函数func:

    function C = mybsxfun(func, A, B)
        idx_A = reshape(1:numel(A), size(A));
        idx_B = reshape(1:numel(B), size(B));
        C = bsxfun(@(ii, jj)func(A(ii), B(jj)), idx_A, idx_B);
    

    如果你的函数可以对整个单元格数组进行元素操作,你可以先对单元格数组执行单例扩展,然后将它们直接提供给函数func:

    mask = bsxfun(@or, true(size(A)), true(size(B)));
    idx_A = bsxfun(@times, mask, reshape(1:numel(A), size(A)));
    idx_B = bsxfun(@times, mask, reshape(1:numel(B), size(B)));
    C = func(A(idx_A), B(idx_B));
    

    如果func针对单元阵列的矢量化操作进行了优化,则后一种方法可能更快。

[str,ia,ib] = intersect(a,b)

?

正如错误消息所示,广播仅适用于数字类型。以下是其他可能的选择:

a = {'aa', 'bb', 'cc'};
b = {'dd'; 'aa'};
%# obviously doesnt work
%#bsxfun(@strcmp, a, b)
%# do the singleton expansion ourselves
strcmp(repmat(a,size(b)), repmat(b,size(a)))
%# if you dislike REPMAT, we can use Tony's trick
strcmp(a(ones(size(b)),:), b(:,ones(size(a))))
%# we could also use CELLFUN
cell2mat(cellfun(@(s)strcmp(a,s), b, 'UniformOutput',false))

相关内容

  • 没有找到相关文章

最新更新