カウントによる要素ごとのアレイレプリケーション[複製
-
24-09-2019 - |
質問
この質問にはすでに答えがあります:
私の質問はこれに似ています 1, 、しかし、同じサイズの2番目の配列で指定されたカウントに従って各要素を複製したいと思います。
この例として、私は配列があったとします v = [3 1 9 4]
, 、使いたいです rep = [2 3 1 5]
最初の要素を2回、2番目の要素を3回複製するために、その他 [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
しかし、私はまだこれを行うためのより賢い方法が必要だと感じています...ありがとう
解決
これが私がこれを達成するのが好きな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
複製された値のグループがどこから始まるかを示します。これらのポイントにはマークが付いています。累積合計が実行される場合 index
, 、インデックスに使用できる最終的なインデックスベクトルを取得します v
不均一に表現された値のベクトルを作成します。
他のヒント
考えられるソリューションのリストに追加するには、これを考えてみてください。
vv = cellfun(@(a,b)repmat(a,1,b), num2cell(v), num2cell(rep), 'UniformOutput',0);
vv = [vv{:}];
これはそれよりもはるかに遅いです GNOVICE..
あなたがしようとしているのはそうです ランレングスデコード. 。高レベルの信頼性/ベクトル化されたユーティリティはです FEXの提出 rude()
:
% example inputs
counts = [2, 3, 1];
values = [24,3,30];
結果
rude(counts, values)
ans =
24 24 3 3 3 30
この関数は反対の操作も実行することに注意してください、つまり ランレングスエンコード ベクトルまたは言い換えれば戻ります values
そして対応する counts
.
accumarray
Zerosが出て行った場合、機能を使用してコードを機能させることができます rep
配列
function vv = repeatElements(v, rep)
index = accumarray(cumsum(rep)'+1, 1);
vv = v(cumsum(index(1:end-1))+1);
end
これは、GNOVICEの溶液と同様に機能しますが、インデックスが1に割り当てられる代わりに蓄積されることを除きます。
>> 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