在MATLAB中映射函数?

97 matlab functional-programming map-function

我有点惊讶MATLAB没有Map功能,所以我自己一起攻击了一个,因为它是我不能没有的东西.那里有更好的版本吗?那里有一个有点标准的MATLAB函数式编程库我不见了吗?

function results = map(f,list)
% why doesn't MATLAB have a Map function?
results = zeros(1,length(list));
for k = 1:length(list)
    results(1,k) = f(list(k));
end

end
Run Code Online (Sandbox Code Playgroud)

用法是例如

map( @(x)x^2,1:10)
Run Code Online (Sandbox Code Playgroud)

gno*_*ice 130

简短的回答:内置函数arrayfun完全符合map函数对数值数组的作用:

>> y = arrayfun(@(x) x^2, 1:10)
y =

     1     4     9    16    25    36    49    64    81   100
Run Code Online (Sandbox Code Playgroud)

还有另外两个内置函数,其行为类似:( cellfun对单元数组的元素进行操作)和structfun(对结构的每个字段进行操作).

但是,如果您利用向量化,特别是使用逐元素算术运算符,则通常不需要这些函数.对于您给出的示例,矢量化解决方案将是:

>> x = 1:10;
>> y = x.^2
y =

     1     4     9    16    25    36    49    64    81   100
Run Code Online (Sandbox Code Playgroud)

某些操作将自动跨元素操作(例如向向量添加标量值),而其他操作符具有用于逐元素操作的特殊语法(.在运算符之前用a表示).在MATLAB许多内置函数被设计为使用元件为单位的运算向量和矩阵参数操作(通常应用到一个给定的尺寸,例如summean例如),和因此不需要地图的功能.

总而言之,这里有一些不同的方法来对数组中的每个元素进行平方:

x = 1:10;       % Sample array
f = @(x) x.^2;  % Anonymous function that squares each element of its input

% Option #1:
y = x.^2;  % Use the element-wise power operator

% Option #2:
y = f(x);  % Pass a vector to f

% Option #3:
y = arrayfun(f, x);  % Pass each element to f separately
Run Code Online (Sandbox Code Playgroud)

当然,对于这种简单的操作,选项#1是最明智(和有效)的选择.

  • 应该注意的是,选项1不仅更简单,而且更快(与选项3相比,2应该非常类似于1)! (2认同)

kwa*_*ord 10

除了矢量和元素操作之外,还有cellfun用于在单元阵列上映射函数的功能.例如:

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans = 
    'A'    'B'    'C'
Run Code Online (Sandbox Code Playgroud)

如果'UniformOutput'为真(或未提供),它将尝试根据单元格数组的尺寸连接结果,所以

cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC
Run Code Online (Sandbox Code Playgroud)


Dim*_*ima 0

如果matlab没有内置map函数,可能是出于效率方面的考虑。在您的实现中,您使用循环来迭代列表的元素,这在 matlab 世界中通常是不受欢迎的。大多数内置 matlab 函数都是“矢量化”的,即在整个数组上调用函数比自己迭代数组并为每个元素调用函数更有效。

换句话说,这


a = 1:10;
a.^2
Run Code Online (Sandbox Code Playgroud)

比这快得多


a = 1:10;
map(@(x)x^2, a)
Run Code Online (Sandbox Code Playgroud)

假设你对地图的定义。

  • 我认为他的观点并不是他希望它必须循环,而只是被指定为将所提供的函数应用于所提供的数组的相应元素的结果数组作为其结果。我不太了解 matlab,但似乎 arrayfun 可以完成这项工作。 (2认同)