Insert zeros in random positions following another zero

4 visualizzazioni (ultimi 30 giorni)
Hi All,
I have a large array such as this one: X = [2 1 0 4 5 0 778 90 0 3 88 0 77 66 0 12 23 0 45 80 0 89 67 0 34 67 0 76 32 0]; (just much larger)
I'd like to insert 20% of additional zeros at random positions following another 0 such as:
new_X = [2 1 0 0 4 5 0 778 90 0 3 88 0 77 66 0 12 23 0 0 45 80 0 89 67 0 34 67 0 76 32 0];
I need to find the indeces of the zeros in X but then I can't get the "random" 20% of zeros correct...
Does anybody know how to do that?
Kind regards
Phil
  1 Commento
Phillip
Phillip il 28 Nov 2023
% This does what I want...but do you know of a quicker way?
X = [2 1 0 4 5 0 778 90 0 3 88 0 77 66 0 12 23 0 45 80 0 89 67 0 34 67 0 76 32 0];
% Find indices of zeros in X
zero_indices = find(X == 0);
% Calculate additional 0s to insert (20% of the total number of 0 in X)
num_existing_zeros = length(zero_indices);
num_additional_zeros = round(0.2 * num_existing_zeros);
% Randomly select positions following existing 0s
additional_zero_positions = randsample(num_existing_zeros, num_additional_zeros);
% Sort 'em
additional_zero_positions = sort(additional_zero_positions);
% Insert 0s
for i = 1:num_additional_zeros
insert_index = zero_indices(additional_zero_positions(i)) + i;
X = [X(1:insert_index+1) 0 X(insert_index+2:end)];
zero_indices = zero_indices + 1;
end

Accedi per commentare.

Risposta accettata

Steven Lord
Steven Lord il 28 Nov 2023
You can use repelem to replicate the elements.
X = [2 1 0 4 5 0 778 90 0 3 88 0 77 66 0 12 23 0 45 80 0 89 67 0 34 67 0 76 32 0];
Start off by "replicating" every element once.
replicationFactor = ones(size(X));
Identify where the zero elements are located.
iszero = X == 0;
zeroLocations = find(iszero)
zeroLocations = 1×10
3 6 9 12 15 18 21 24 27 30
numZeros = numel(zeroLocations)
numZeros = 10
Let's select 20% of the 0 locations (rounded up) to replicate twice. To do this, update the selected element in replicationFactor from 1 to 2.
elementsInZeroLocationsToReplicate = randperm(numZeros, ceil(0.2*numZeros));
randomSelection = zeroLocations(elementsInZeroLocationsToReplicate)
randomSelection = 1×2
6 15
replicationFactor(randomSelection) = 2
replicationFactor = 1×30
1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Now replicate with repelem.
Y = repelem(X, replicationFactor)
Y = 1×32
2 1 0 4 5 0 0 778 90 0 3 88 0 77 66 0 0 12 23 0 45 80 0 89 67 0 34 67 0 76

Più risposte (1)

Davide Masiello
Davide Masiello il 28 Nov 2023
Modificato: Davide Masiello il 28 Nov 2023
This should work without the need for a for loop.
X = [2 1 0 4 5 0 778 90 0 3 88 0 77 66 0 12 23 0 45 80 0 89 67 0 34 67 0 76 32 0];
Select two random locations and increase the index by one (i.e. the new zero goes after the old random zero).
idx = sort(randsample(find(X==0),2));
idx = idx+[1:length(idx)]
idx = 1×2
4 32
Create a new vector of NaNs of the length required for the new vector.
newX = nan(1,length(X)+length(idx));
First place the new additional zeros.
newX(idx) = 0;
Then add the old vector where the NaNs are left.
newX(isnan(newX)) = X;
See the result below
disp(newX)
2 1 0 0 4 5 0 778 90 0 3 88 0 77 66 0 12 23 0 45 80 0 89 67 0 34 67 0 76 32 0 0

Categorie

Scopri di più su Random Number Generation in Help Center e File Exchange

Prodotti


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by