对于非数值数据是否有与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);
恐怕没有这样的等效单元格数组:-(
)在我看来,你可以:
- 遵循Oleg的建议并使用循环
- 使用现有的实现,如
mAryCellFcn
或从文件交换csxfun
滚动您自己的函数。例如,下面是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))