Randomly select a set number of samples (of size n) without overlap, nor replacement, in a signal

조회 수: 3 (최근 30일)
I have a sound signal and I would like to randomly select 5 units of 10 seconds in that signal, but with no overlap, and with no replacement. It looks like I cannot use the function datasample because it only sample 1 sample in the vector (whereas I need: n = 10 seconds * sampling frequency).
If it is possible, I also would like a buffer length of b samples in between each unit sampled.
Any help much appreciated! Thank you!
  댓글 수: 3
Butterflyfish
Butterflyfish 2019년 12월 8일
Sorry for the misunderstanding. Let's say the signal is 10 minutes total. I would like to sample 5 units of data randomly in the signal (vector). Each unit would need to be 10 seconds and at least a distance of b between them. The units should not overlap.
Turlough Hughes
Turlough Hughes 2019년 12월 8일
Find out how many 10 second segments you have, assign a number to each segment and use randperm to get a random 5 samples non repeating. Can you attach the data to the question.

댓글을 달려면 로그인하십시오.

채택된 답변

Image Analyst
Image Analyst 2019년 12월 8일
Try this:
% Set up the signal and sampling parameters
samplingFrequency = 100; % Samples per second.
totalSeconds = 6000 % 6000
totalSamples = ceil(totalSeconds * samplingFrequency)
numRequiredSeconds = 10;
numRequiredSamples = ceil(numRequiredSeconds * samplingFrequency)
signal = rand(1, totalSamples);
numRequiredSegments = 5
segmentCount = 0;
iterations = 0;
maxIterations = 100000; % Some huge number where if we reach this, we will assume that the required number of segments can't be found randomly.
% Now look for acceptable non-overlapping segments.
while segmentCount < numRequiredSegments && iterations < maxIterations
% Get a random starting and stopping points for one segment.
thisStartingIndex = randi(totalSamples, 1);
thisStoppingIndex = thisStartingIndex + numRequiredSamples - 1;
% See if any indexes in this range overlap any prior indexes.
okay = true;
if iterations > 0
for k = 1 : iterations
% See if starting index is inside any existing segment.
if thisStartingIndex >= startingIndexes(k) && thisStartingIndex <= stoppingIndexes(k)
okay = false;
end
% See if stopping index is inside any existing segment.
if thisStoppingIndex >= startingIndexes(k) && thisStoppingIndex <= stoppingIndexes(k)
okay = false;
end
end
end
if okay
% If we get to here, the segment is okay - no overlapping with prior segments.
% Record the starting and stopping index of this segment, since it's okay.
segmentCount = segmentCount + 1; % Increment the index of this particular segment.
startingIndexes(segmentCount) = thisStartingIndex;
stoppingIndexes(segmentCount) = thisStoppingIndex;
fprintf('Found a good segment on iteration #%d. Starting Index = %d. Stopping Index = %d.\n', ...
iterations, thisStartingIndex, thisStoppingIndex);
end
% Increment the loop counter.
iterations = iterations + 1;
fprintf('Done with iteration #%d.\n', iterations);
end
% Optional: sort
[startingIndexes, sortOrder] = sort(startingIndexes, 'ascend');
stoppingIndexes = stoppingIndexes(sortOrder);
% Display sorted indexes in the command window.
for k = 1 : length(startingIndexes)
fprintf('Segment #%d: Starting Index = %d. Stopping Index = %d.\n', ...
k, startingIndexes(k), stoppingIndexes(k));
end
You'll see in the command window:
Segment #1: Starting Index = 132291. Stopping Index = 133290.
Segment #2: Starting Index = 202347. Stopping Index = 203346.
Segment #3: Starting Index = 371253. Stopping Index = 372252.
Segment #4: Starting Index = 568586. Stopping Index = 569585.
Segment #5: Starting Index = 582577. Stopping Index = 583576.
  댓글 수: 5
Butterflyfish
Butterflyfish 2020년 1월 17일
편집: Butterflyfish 2020년 1월 17일
Sorry I erased my last comment by mistake. So the problem is now that I get segments smaller than the required number of samples. Which give me this output, for example:
Found a good segment on iteration #0. Starting Index = 18586722. Stopping Index = 19909721.
Done with iteration #0.
Found a good segment on iteration #1. Starting Index = 16550163. Stopping Index = 17873162.
Done with iteration #1.
Found a good segment on iteration #2. Starting Index = 13293809. Stopping Index = 14616808.
Done with iteration #2.
Found a good segment on iteration #3. Starting Index = 26312898. Stopping Index = 26460000.
Done with iteration #3.
Done with iteration #4.
Done with iteration #5.
Done with iteration #6.
Found a good segment on iteration #7. Starting Index = 21787214. Stopping Index = 23110213.
Done with iteration #7.
Segment #1: Starting Index = 13293809. Stopping Index = 14616808.
Segment #2: Starting Index = 16550163. Stopping Index = 17873162.
Segment #3: Starting Index = 18586722. Stopping Index = 19909721.
Segment #4: Starting Index = 21787214. Stopping Index = 23110213.
Segment #5: Starting Index = 26312898. Stopping Index = 26460000.
Unable to perform assignment because the indices on the left side are not compatible with the size of the right
side.
Error in test (line 71)
segments(:,k) = soundfile(startingIndexes(k):stoppingIndexes(k),1);
Here is a folder with the script and a signal as an example:
Many thanks for your help ! Invaluable!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Just for fun에 대해 자세히 알아보기

제품


릴리스

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by