Insert zeros in random positions following another zero

1 view (last 30 days)
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 Comment
Phillip
Phillip on 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

Sign in to comment.

Accepted Answer

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

More Answers (1)

Davide Masiello
Davide Masiello on 28 Nov 2023
Edited: Davide Masiello on 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

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!