8

私の質問はこれに似ていますが、同じサイズの2番目の配列で指定されたカウントに従って各要素を複製したいと思います。

この例として、配列がある場合、最初の要素を2回複製し、次の要素を3回複製するv = [3 1 9 4]ために使用したい、というように取得します。rep = [2 3 1 5][3 3 1 1 1 9 4 4 4 4 4]

これまでのところ、私は仕事を成し遂げるために単純なループを使用しています。これは私が始めたものです:

vv = [];
for i=1:numel(v)
    vv = [vv repmat(v(i),1,rep(i))];
end

スペースを事前に割り当てることで、なんとか改善できました。

vv = zeros(1,sum(rep));
c = cumsum([1 rep]);
for i=1:numel(v)
    vv(c(i):c(i)+rep(i)-1) = repmat(v(i),1,rep(i));
end

しかし、私はまだこれを行うためのより賢い方法が必要だと感じています...ありがとう

4

4 に答える 4

16

これを達成するために私が好きな方法の1つは次のとおりです。

>> index = zeros(1,sum(rep));
>> index(cumsum([1 rep(1:end-1)])) = 1;

index =

     1     0     1     0     0     1     1     0     0     0     0

>> index = cumsum(index)

index =

     1     1     2     2     2     3     4     4     4     4     4

>> vv = v(index)

vv =

     3     3     1     1     1     9     4     4     4     4     4

これは、すべての値の最終カウントと同じ長さのゼロのインデックス ベクトルを最初に作成することによって機能します。rep最後の要素を削除し、先頭に 1 を配置してベクトルの累積和をindex計算することで、複製された値のグループがどこから始まるかを示すインデックスのベクトルを取得します。これらの点は 1 でマークされています。で累積合計が実行されるとindex、最終的なインデックス ベクトルが得られます。このベクトルを使用してインデックスvを作成し、異種の複製値のベクトルを作成できます。

于 2010-03-04T20:10:12.813 に答える
2

可能な解決策のリストに追加するには、次のことを検討してください。

vv = cellfun(@(a,b)repmat(a,1,b), num2cell(v), num2cell(rep), 'UniformOutput',0);
vv = [vv{:}];

これはgnoviceによるものよりもはるかに遅いです..

于 2010-03-04T20:46:57.557 に答える
0

accumarrayゼロがrep配列に存在する場合、関数を使用してコードを機能させることができます

function vv = repeatElements(v, rep)
index = accumarray(cumsum(rep)'+1, 1);
vv = v(cumsum(index(1:end-1))+1);
end

これは、1 に割り当てられる代わりにインデックスが累積されることを除いて、gnovice のソリューションと同様に機能します。これにより、いくつかのインデックス (以下の例では 3 と 6) をスキップし、対応する要素を出力から削除できます。

>> v = [3 1 42 9 4 42];
>> rep = [2 3 0 1 5 0];
>> index = accumarray(cumsum(rep)'+1, 1)'

index =

     0     0     1     0     0     2     1     0     0     0     0     2

>> cumsum(index(1:end-1))+1

ans =

     1     1     2     2     2     4     5     5     5     5     5

>> vv = v(cumsum(index(1:end-1))+1)

vv =

     3     3     1     1     1     9     4     4     4     4     4
于 2014-10-17T12:01:45.910 に答える
0

あなたがやろうとしているのは、ランレングスのデコードです。高レベルの信頼できる/ベクトル化されたユーティリティは、FEX サブミッションrude()です。

% example inputs
counts = [2, 3, 1];
values = [24,3,30];

結果

rude(counts, values)
ans =
    24    24     3     3     3    30

この関数は逆の操作も実行することに注意してください。つまり、ランレングスはベクトルをエンコードします。つまり、戻り値valuesと対応するcounts.

于 2013-08-21T13:23:49.443 に答える