Shuffle row order within every N rows in a matrix
4 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Benjy Barnett
el 9 de Feb. de 2023
Comentada: Rik
el 10 de Feb. de 2023
I would like to shuffle my matrix's rows, but within each miniblock of 8 rows.
So for example, say I have the following 16x5 matrix:
[1 2 4 1 1
1 2 4 2 1
1 2 4 1 2
1 2 4 2 2
1 2 4 1 1
1 2 4 2 1
1 2 4 1 2
1 2 4 2 2
1 2 1 1 1
1 2 1 2 1
1 2 1 1 2
1 2 1 2 2
1 2 1 1 1
1 2 1 2 1
1 2 1 1 2
1 2 1 2 2];
How can I shuffle it so that the first 8 rows are all shuffled with eachother (maintaining column structure), and the second set of 8 rows are shuffled with eachother? Producing something like this:
[1 2 4 1 1
1 2 4 2 2
1 2 4 2 1
1 2 4 1 1
1 2 4 1 2
1 2 4 1 2
1 2 4 2 2
1 2 4 2 1
1 2 1 1 1
1 2 1 1 1
1 2 1 1 2
1 2 1 2 1
1 2 1 2 2
1 2 1 2 1
1 2 1 1 2
1 2 1 2 2];
In reality, my matrix is 384x5, so would be nice to be able to automate this somehow.
3 comentarios
Luca Ferro
el 9 de Feb. de 2023
why there is always a plot twist after people start answering lol :)
Respuesta aceptada
Voss
el 9 de Feb. de 2023
Here's one way:
I'll use a different matrix that makes it easier to see that the process works:
data = repmat((1:8).'+(0:4),2,1);
disp(data);
n_rows = 8;
N = size(data,1); % N must be a multiple of n_rows for this to work
n_shuffles = N/n_rows;
idx = zeros(n_rows,n_shuffles);
for ii = 1:n_shuffles
idx(:,ii) = randperm(n_rows);
end
new_data = data(idx(:),:);
disp(new_data);
1 comentario
Rik
el 10 de Feb. de 2023
If your matrix is not a multiple of n_rows, you need edits like in my answer.
Más respuestas (2)
Luca Ferro
el 9 de Feb. de 2023
Editada: Luca Ferro
el 9 de Feb. de 2023
i think this would do the trick:
[rows,~]=size(m);
if mod(rows,2)==0 %detects if even or odd number of rows
half=rows/2;
topHalf=m(1:half,:) %split matrix in half
bottomHalf=m(1+half :end,:)
else
half=(rows+1)/2; %the middle row will be left unshuffled
topHalf=m(1:half-1,:) %split matrix in half
bottomHalf=m(1+half :end,:)
end
topShuffle=randperm(half);
bottomShuffle=randperm(half);
m=[topHalf(topShuffle,:);bottomHalf(bottomShuffle,:)] %merges halves to recreate full
0 comentarios
Rik
el 9 de Feb. de 2023
Just use a loop with randperm:
data=[
1 2 4 1 1
1 2 4 2 1
1 2 4 1 2
1 2 4 2 2
1 2 4 1 1
1 2 4 2 1
1 2 4 1 2
1 2 4 2 2
1 2 1 1 1
1 2 1 2 1
1 2 1 1 2
1 2 1 2 2
1 2 1 1 1
1 2 1 2 1
1 2 1 1 2
1 2 1 2 2];
k=4; % You want 8, but that is a big example
rng(0) % make the result the same each run for this example
sz = size(data,1);
for base_row=1:k:sz
base_row
block_indices = randperm( min(sz-base_row,k) );
ind1 = base_row + (1:numel(block_indices))
ind2 = base_row + block_indices
data(ind2,:) = data(ind1,:);
end
0 comentarios
Ver también
Categorías
Más información sobre Resizing and Reshaping Matrices en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!