Shuffle row order within every N rows in a matrix
5 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
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 Kommentare
Akzeptierte Antwort
Voss
am 9 Feb. 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 Kommentar
Weitere Antworten (2)
Luca Ferro
am 9 Feb. 2023
Bearbeitet: Luca Ferro
am 9 Feb. 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 Kommentare
Rik
am 9 Feb. 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 Kommentare
Siehe auch
Kategorien
Mehr zu Resizing and Reshaping Matrices finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!