Filter löschen
Filter löschen

Insert zeros in random positions following another zero

4 Ansichten (letzte 30 Tage)
Phillip
Phillip am 28 Nov. 2023
Kommentiert: Phillip am 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 Kommentar
Phillip
Phillip am 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

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

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

Weitere Antworten (1)

Davide Masiello
Davide Masiello am 28 Nov. 2023
Bearbeitet: Davide Masiello am 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

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Produkte


Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by