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 件のコメント
Image Analyst
Image Analyst 2020 年 1 月 17 日
Can you attach the file that is causing this problems?
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 Center および File ExchangeJust for fun についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by