gpt4 book ai didi

arrays - 在 MATLAB 中,cellfun 总是可以用 arrayfun 替换吗?

转载 作者:行者123 更新时间:2023-12-02 11:44:30 24 4
gpt4 key购买 nike

我在 MATLAB 2007 中找到了一个示例,其中 cellfunarrayfun 几乎可以互换使用:

>> cellfun(@(c) c, {'one' 'two' 'three'}, 'uniformoutput', 0)
% ans =
% 'one' 'two' 'three'
>> arrayfun(@(c) c, {'one' 'two' 'three'})
% ans =
% 'one' 'two' 'three'

我还可以想到一个 arrayfun 有效但 cellfun 无效的示例:

>> arrayfun(@(c) c, [1 2 3])
% ans =
% 1 2 3
>> cellfun(@(c) c, [1 2 3])
% ??? Error using ==> cellfun
% Input #2 expected to be a cell array, was double instead.

我的问题是:是否存在 cellfun 有效但 arrayfun 无效的情况?如果是,请举例。如果不是,为什么 cellfun 还需要存在?

最佳答案

这很有趣。您的示例正在执行两种不同的操作,这恰好会导致相同的结果。探索起来很有趣。

TL;博士。当您的输入是数组时,您通常应该使用 arrayfun;当您的输入是单元格时,您应该使用 cellfun,尽管您通常可以强制 arrayfun 这样做这项工作具有不同程度的语法 hell 。

从根本上来说,arrayfun 旨在对数组进行操作,cellfun 旨在对单元进行操作。但是,Matlab 会注意到单元格只不过是“单元格”数组,因此 arrayfun 无论如何都可以工作。

<小时/>

正如您所指出的,以下两行执行相同的操作:

cellfun(@(c) c, {'one' 'two' 'three'}, 'uniformoutput', 0)   %returns  {'one' 'two' 'three'}
arrayfun(@(c) c(1), {'one' 'two' 'three'}); %returns {'one' 'two' 'three'}

但是,如果我们想在操作过程中做一些事情,那就有点不同了。例如,我们可能想要提取每个字符串的第一个字符。在这里比较 cellfunarrayfun 的结果:

cellfun( @(c) c(1), {'one' 'two' 'three'}, 'uniformoutput', 0);  %returns {'o' 't' 't'}
arrayfun(@(c) c(1), {'one' 'two' 'three'}); %Returns {'one' 'two' 'three'}

要与 arrayfun 获得相同的结果,我们需要在匿名函数内取消引用单元格,然后提取字符,然后将结果放入单元格数组而不是字符数组中。像这样:

arrayfun(@(c) c{1}(1), {'one' 'two' 'three'},'uniformoutput',false)  %Returns {'o' 't' 't'}
<小时/>

因此,区别在于 cellfun 负责取消引用操作,这是在循环时对单元格的各个元素执行详细操作所需的操作(即 {}),而 arrayfun 仅执行标准索引(即 ())。此外,'uniformoutput',false 表示法确定输出是否写入常规数组或元胞数组。

要显示这在代码中的含义,请参阅以下函数,它们相当于 cellfunarrayfun,无论是否带有 'uniformoutput',false 符号。除了在循环中使用 (){} 之外,这四个函数是等效的:

function out = cellFunEquivalent(fn, x)
for ix = numel(x):-1:1
out(ix) = fn(x{ix});
end
out = reshape(out,size(x));
end

function out = arrayFunEquivalent(fn, x)
for ix = numel(x):-1:1
out(ix) = fn(x(ix));
end
out = reshape(out,size(x));
end

function out = cellFunEquivalent_nonuniform(fn, x)
for ix = numel(x):-1:1
out{ix} = fn(x{ix});
end
out = reshape(out,size(x));
end

function out = arrayFunEquivalent_nonuniform(fn, x)
for ix = numel(x):-1:1
out{ix} = fn(x(ix));
end
out = reshape(out,size(x));
end

对于您发布的示例,arrayfun 函数实际上对单个元素单元格进行操作,并将这些单元格的副本重建为同一(单元格)类的另一个数组(请参阅arrayFunEquivalent )。 cellfun 操作取消引用输入元胞数组的每个元素,然后将这些字符串的副本重建到元胞数组中(请参阅 cellFunEquivalent_nonuniform)。当输入x是单元格时,这些操作是等效的。

关于arrays - 在 MATLAB 中,cellfun 总是可以用 arrayfun 替换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18239129/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com