2

データの一部と、セット内でデータが発生した回数を説明する 2 列のマトリックスがあります。

A = [1    6                              
     2    2
     3    8                                                                       
     4    1 
     5    3];

それを考えると、基になるデータセットを生成する「エレガントな」方法はありますか? つまり、

B = [1 1 1 1 1 1 2 2 3 3 3 3 3 3 3 3 4 5 5 5];                                       

BからA( 、 andtabulateなどを使用して)に移動する方法はたくさんありますが、 から に移動する方法が見つかりませんでした。私ができる最善のことはエレガントではありません:uniquehistcAB

B = [];
for ii = 1:size(A,1)
    B = [B repmat(A(ii,1), 1, A(ii,2))];
end

これを行う「正しい」方法はbsxfunorを使用することだとこっそり疑っていますaccumarrayが、これらが実際にどのように機能するかを理解するのに十分な経験がありません。

4

5 に答える 5

2

もう1つのオプションがあります。エレガントとは言えませんが、かなり効率的です。

ndx = cumsum([1; A(:,2)]);
B = zeros(1, ndx(end)-1);
B(ndx(1:end-1)) = 1;
B = A(cumsum(B), 1).';
于 2013-09-10T18:00:12.923 に答える
2

「arrayfun」を「cell2mat」と組み合わせて使用​​できます。

 B = cell2mat(arrayfun(@(x,y) ones(y,1)*x, A(:,1), A(:,2), 'uniformoutput', false))'

これにより、

B =

  Columns 1 through 16

     1     1     1     1     1     1     2     2     3     3     3     3     3     3     3     3

  Columns 17 through 20

     4     5     5     5
于 2013-09-10T17:49:37.903 に答える
1

どちらも非常にエレガントではありませんが、これはうまくいくかもしれません:

B = {A(:,1)*ones(1,A(:,2)};
B = [B{:}];

構文をチェックするためのmatlabがありません。アイデアはループを削除することです

B=[];
for ii=1:size(A,1)
   B=[B A(i,1)*ones(1,A(i,2)];
end;
于 2013-09-10T17:36:08.187 に答える
1

を使用したソリューションは次のbsxfunとおりです。

B = A(1+sum(bsxfun(@lt, cumsum(A(:,2)), 1:sum(A(:,2)))), 1).';
于 2013-09-10T19:45:20.777 に答える
0

This is similar to H.Muster post

using repmat

B=cell2mat(arrayfun(@(x,y)(repmat(x,y,1) ), A(:,1), A(:,2), ...
                                   'UniformOutput', false));

B' is expected output.

于 2013-09-10T18:05:49.043 に答える