创建具有相同行的新表的有效方法,但是每个表重复不同的次数

时间:2018-08-17 10:10:20

标签: matlab optimization vectorization

假设我创建此表和值数组:

names = {'a'; 'b'; 'c'; 'd'} ; values = {'1'; '2'; '3'; '4'};
originalTable = table(names, values, 'VariableNames', {'names', 'values'});

nRepeat = [10, 50, 100, 2] ;

我想创建一个新表,其中将每行重复nRepeat对应索引的次数,即我将第一行或原始表重复10次,然后将原始表的第二行重复重复50次,依此类推... 此外,我想在该新表中添加一列带有重复索引。

我做了什么:

% Initialize newTable to allocate memory space
totalRepetitions = sum(nRepeat) ;

% Repeated first row of the original table the same number of times as the totalRepetitions that will happen, also adding the new column with the index of repetition
newTable = repmat([originalTable(1,:), array2table(1, 'VariableNames', {'idxRepetition'})], totalRepetitions , 1) ;

addedRows = 0 ;
for idxName = 1 : numel(originalTable.names)

    newTable(addedRows +1 : addedRows + nRepeat(idxName) , :) =...
        [repmat(originalTable(idxName ,:), nRepeat(idxName), 1), array2table( (1:1:nRepeat(idxName))', 'VariableNames', {'idxRepetition'}) ] ;

    addedRows = addedRows + nRepeat(idxName);
end

这有效,但是对于大桌子却变得缓慢。

有没有更有效的方法?

2 个答案:

答案 0 :(得分:7)

您只需在索引上使用repelem

indx = repelem((1:numel(nRepeat)),nRepeat);
idxrep = arrayfun(@(x) 1:1:x,nRepeat,'un',0)'
finalTable = [originalTable(indx, :), table([idxrep{:}]','VariableNames', {'idxRepetition'})];

finalTable:

162×3 table

names    values    idxRepetition
_____    ______    _____________

 'a'      '1'             1     
 'a'      '1'             2     
 'a'      '1'             3     
 'a'      '1'             4     
 'a'      '1'             5     
 'a'      '1'             6     
 'a'      '1'             7     
 'a'      '1'             8     
 'a'      '1'             9     
 'a'      '1'            10     
 'b'      '2'             1     
 'b'      '2'             2     
 'b'      '2'             3  

答案 1 :(得分:4)

这怎么样?

Irep = arrayfun(@(n) n*ones(1,nRepeat(n)), 1:length(nRepeat),'UniformOutput',false); 
Irep = [Irep{:}]';
Iidx = arrayfun(@(n) 1:nRepeat(n), 1:length(nRepeat),'UniformOutput',false); 
Iidx = [Iidx{:}]';
newTable = table(names(Irep),values(Irep), Iidx, 'VariableNames', {'names', 'values','idxRepetition'});

输出以下内容:

newTable =

  162×3 table

    names    values    idxRepetition
    _____    ______    _____________

    'a'      '1'         1          
    'a'      '1'         2          
    'a'      '1'         3          
    'a'      '1'         4          
    'a'      '1'         5          
    'a'      '1'         6          
    'a'      '1'         7          
    'a'      '1'         8          
    'a'      '1'         9          
    'a'      '1'        10          
    'b'      '2'         1          
    'b'      '2'         2          
    'b'      '2'         3          
    'b'      '2'         4          
    'b'      '2'         5          
    ...