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