函数式编程 - MATLAB中的Map函数?
我对MATLAB没有地图功能感到有些惊讶,所以我自己一起攻击了一个,因为它是我无法生存的东西。 那里有更好的版本吗? 有没有一个有点标准的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
用法是例如
map( @(x)x^2,1:10)
7个解决方案
129 votes
简短回答:内置函数mean完全符合您的mean函数对数值数组的作用:
>> y = arrayfun(@(x) x^2, 1:10)
y =
1 4 9 16 25 36 49 64 81 100
还有两个其他类似行为的内置函数:mean(对单元格数组元素进行操作)和mean(对结构的每个字段进行操作)。
但是,如果您利用向量化,特别是使用逐元素算术运算符,则通常不需要这些函数。 对于您给出的示例,矢量化解决方案将是:
>> x = 1:10;
>> y = x.^2
y =
1 4 9 16 25 36 49 64 81 100
一些操作将自动跨元素操作(例如向向量添加标量值),而其他操作符具有用于逐元素操作的特殊语法(在操作符之前由mean表示)。 MATLAB中的许多内置函数被设计为使用逐元素操作(通常应用于给定维度,例如mean和mean)对向量和矩阵参数进行操作,因此不需要映射函数。
总而言之,这里有一些不同的方法来对数组中的每个元素进行平方:
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
当然,对于这种简单的操作,选项#1是最明智(和有效)的选择。
gnovice answered 2019-08-12T02:33:52Z
10 votes
除了向量和元素操作之外,还有用于在单元阵列上映射函数的cellfun。 例如:
cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans =
'A' 'B' 'C'
如果' UniformOutput' 如果是真的(或没有提供),它将尝试根据单元格数组的尺寸连接结果,所以
cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC
kwatford answered 2019-08-12T02:34:26Z
2 votes
一个相当简单的解决方案,使用Matlab的矢量化将是:
a = [ 10 20 30 40 50 ]; % the array with the original values
b = [ 10 8 6 4 2 ]; % the mapping array
c = zeros( 1, 10 ); % your target array
现在,打字
c( b ) = a
回报
c = 0 50 0 40 0 30 0 20 0 10
c(b)是对大小为5的向量的引用,其中c的元素由b给出。 现在,如果为这个参考向量赋值,则c中的原始值将被覆盖,因为c(b)包含对c中值的引用而没有副本。
doc answered 2019-08-12T02:35:06Z
1 votes
如果所需的结果是一个函数数组,似乎内置的arrayfun不起作用:例如: 地图(@(x)[x x ^ 2 x ^ 3],1:10)
下面的轻微mods使这项工作更好:
function results = map(f,list)
% why doesn't MATLAB have a Map function?
for k = 1:length(list)
if (k==1)
r1=f(list(k));
results = zeros(length(r1),length(list));
results(:,k)=r1;
else
results(:,k) = f(list(k));
end;
end;
end
Foo Bara answered 2019-08-12T02:35:38Z
0 votes
如果matlab没有内置的map功能,那可能是出于效率考虑。 在您的实现中,您使用循环来迭代列表的元素,这在matlab世界中通常是不受欢迎的。 大多数内置的matlab函数都是"矢量化",i。即 在整个数组上调用函数比在自己迭代它并为每个元素调用函数更有效。
换句话说,这个
a = 1:10;
a.^2
比这快得多
a = 1:10;
map(@(x)x^2, a)
假设您定义地图。
Dima answered 2019-08-12T02:36:24Z
0 votes
您不需要map,因为应用于值列表的标量函数将应用于每个值,因此类似于map。只需尝试
l = 1:10
f = @(x) x + 1
f(l)
在你的特殊情况下,你甚至可以写
l.^2
Dario answered 2019-08-12T02:36:56Z
-1 votes
如前面的答案所述,对解决方案进行矢量化可能是速度的最佳解决方案。 矢量化也非常Matlaby,感觉很好。
据说Matlab现在有一个Map容器类。
见[http://www.mathworks.com/help/matlab/map-containers.html]
TallBrianL answered 2019-08-12T02:37:35Z