arrayfun 当数组的每一行作为输入时

6

我的情况是,我想通过一个将行向量映射到行向量的句柄为fun的函数来映射标量数组A,以获取B,使得B(i,:)=fun(A(i,:))

我能想到的最合理的解决方案如下:

temp = mat2cell(A,ones(1,size(A,1)),size(A,2));
B = cell2mat(cellfun(fun,temp,'UniformOutput',0));

然而,将其转换为单元格再转回去似乎有些过分(并且可能是计算上昂贵的)。而且我不清楚为什么cellfun会抱怨非均匀输出。您是否想到了更有效的方法?


4个回答

4

还有一种解决方案是使用accumarray。虽然不像bsxfun那么高级,但它不需要声明帮助函数:

subs = ndgrid(1:size(A, 1));
B = accumarray(subs(:), A(:), [], @fun); %// @fun is the function handle

3

我知道这是一篇旧帖子,但如果有其他人看到这篇文章,Matlab在2013b版本中添加了rowfun功能,它可以计算表格的行并返回列向量。以下是一个例子:

f = @(c) sum(c.^2);

x=[1 2;
   3 4;
   5 6];

z=table2array(rowfun(f,table(x)))

z=
   5
  25
  61

3

您可以使用bsxfun在不使用单元数组的情况下完成此操作。

使用Marcin提供的示例数据和函数:

A =[ 0.5669    0.4315    0.4515    0.7664    0.5923; ...
     0.8337    0.7317    0.4898    0.2535    0.7506; ...
     0.3321    0.5424    0.4585    0.8004    0.9564];

fun = @(x,y) x*2;
B= bsxfun(fun,A,1);

B =

    1.1338    0.8630    0.9030    1.5328    1.1846
    1.6674    1.4634    0.9796    0.5070    1.5012
    0.6642    1.0848    0.9170    1.6008    1.9128

编辑:

正如Eitan所指出的,上述代码中的fun可能需要成为您“真正”的匿名函数的包装器,因此更完整的解决方案是:

fun = @(x) x *2;        % Replace with actual anonymous function
fun2 = @(x,y) fun(x);   % Wrapper on fun to discard unused 2nd parameter
B= bsxfun(fun2,A,1);

很好地运用了bsxfun,但是这个函数是逐个对a中的一个值应用,还是逐行应用的? - Marcin
@Marcin 如果将标量作为数组之一传递给bsxfun,则bsxfun将执行标量扩展并将其应用于另一个数组的每个元素(最近的一个问题涉及到这个问题)。 - Eitan T
@grantnz +1,但问题中的“fun”是一元的。您应该注意到,您的“fun”是一个包装函数,定义为在“bsxfun”中使用... - Eitan T
@EitanT。是的,这个解决方案确实需要一个简单的包装器来丢弃未使用的第二个参数,尽管如果主要函数是匿名函数,它可以轻松地丢弃虚拟的第二个参数。 - grantnz
1
@grantnz 容易,没问题。但需要注意的是,乍一看似乎你正在将原始函数传递给 bsxfun - Eitan T

2
我认为如果我理解您想要做的事情,您可以按照以下步骤进行:

我认为您可以按照以下步骤进行,如果我理解您想要做的事情:

A = rand(3, 5);
fun = @(x) x*2;
B = cell2mat(arrayfun(@(i) fun(A(i, :)), 1:size(A, 1), 'UniformOutput', false)');

% example results:
A =

    0.5669    0.4315    0.4515    0.7664    0.5923
    0.8337    0.7317    0.4898    0.2535    0.7506
    0.3321    0.5424    0.4585    0.8004    0.9564


B =

    1.1338    0.8630    0.9030    1.5328    1.1845
    1.6675    1.4635    0.9795    0.5071    1.5013
    0.6642    1.0848    0.9169    1.6008    1.9128

这将对A中的每个行应用fun。这是基于这里的帖子。在那里,您还可以找到更多信息和解释,以及应用函数到数组行的替代方法。


你的实现看起来和我的一模一样。我会在另一个线程中查看更多信息——我仍然很好奇将其转换为单元格是否是最明智的方法。 - Eugene Shvarts
谢谢,我也遇到了同样的问题,这似乎是实现正确结果最简单的方法。 - Realhermit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接