103

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

使用法は例えば

map( @(x)x^2,1:10)
4

7 に答える 7

137

簡単な答え: 組み込み関数は、関数が数値配列に対して行うarrayfunこととまったく同じことを行います。map

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

     1     4     9    16    25    36    49    64    81   100

同様に動作する組み込み関数が他に 2 つあります。cellfun(cell 配列の要素を操作する) とstructfun(構造体の各フィールドを操作する) です。

ただし、ベクトル化を利用する場合、特に要素ごとの算術演算子を使用する場合、これらの関数は必要ないことがよくあります。あなたが与えた例では、ベクトル化されたソリューションは次のようになります。

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

     1     4     9    16    25    36    49    64    81   100

一部の操作は要素全体で自動的に処理されますが (スカラー値をベクトルに追加するなど)、他の演算子には要素単位の操作用の特別な構文があります (.演算子の前に a で示されます)。MATLAB の多くの組み込み関数は、要素ごとの演算 (多くの場合、 や などの特定の次元に適用される) を使用してベクトルおよび行列の引数を操作するように設計されているためsummeanマップ関数は必要ありません。

要約すると、配列内の各要素を 2 乗するいくつかの異なる方法を次に示します。

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 が最も賢明な (そして効率的な) 選択です。

于 2009-06-11T19:48:38.483 に答える
10

ベクトルと要素単位の演算に加えて、cellfunセル配列に対する関数のマッピングもあります。例えば:

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans = 
    'A'    'B'    'C'

'UniformOutput' が true (または指定されていない) の場合、cell 配列の次元に従って結果を連結しようとします。

cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC
于 2009-06-11T20:17:05.153 に答える
2

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)は、bで与えられるインデックスにcの要素を持つサイズ5のベクトルへの参照です。ここで、この参照ベクトルに値を割り当てると、c(b)にはcの値への参照が含まれ、コピーが含まれないため、cの元の値が上書きされます。

于 2011-11-17T14:09:29.340 に答える
1

必要な結果が関数の配列である場合、組み込みの arrayfun は機能しないようです: 例: map(@(x)[xx^2 x^3],1:10)

以下のわずかな変更により、この作業が改善されます。

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
于 2012-04-26T10:39:17.223 に答える
0

map値のリストに適用されるスカラー関数は各値に適用され、したがって と同様に機能するため、必要ありませんmap。ちょうど試して

l = 1:10
f = @(x) x + 1

f(l)

あなたの特定のケースでは、書くことさえできます

l.^2
于 2009-06-11T19:54:21.183 に答える
0

matlab に map 関数が組み込まれていない場合は、効率性を考慮している可能性があります。実装では、ループを使用してリストの要素を反復処理していますが、これは一般的に matlab の世界では嫌われています。ほとんどの組み込みの matlab 関数は "ベクトル化" されています。つまり、自分で反復して各要素に対して関数を呼び出すよりも、配列全体で関数を呼び出す方が効率的です。

つまり、これは


a = 1:10;
a.^2

これよりずっと速い


a = 1:10;
map(@(x)x^2, a)

マップの定義を仮定します。

于 2009-06-11T19:48:34.597 に答える
-1

前の回答で説明されているようにソリューションをベクトル化することは、おそらく速度の最適なソリューションです。ベクトル化もとてもMatlabyで気持ちいいです。

そうは言っても、Matlab には Map コンテナー クラスがあります。

http://www.mathworks.com/help/matlab/map-containers.htmlを参照してください。

于 2014-05-02T21:34:05.013 に答える