Insert zeros in random positions following another zero

3 vues (au cours des 30 derniers jours)
Phillip
Phillip le 28 Nov 2023
Commenté : Phillip le 28 Nov 2023
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 commentaire
Phillip
Phillip le 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

Connectez-vous pour commenter.

Réponse acceptée

Steven Lord
Steven Lord le 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

Plus de réponses (1)

Davide Masiello
Davide Masiello le 28 Nov 2023
Modifié(e) : Davide Masiello le 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

Catégories

En savoir plus sur Random Number Generation dans Help Center et File Exchange

Produits


Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by