假设我有一个包含44100个样本的文件,采样率为fs = 44100 Hz。 所以我的文件长1秒。
我想将其下采样到8 Hz的采样频率,但我想这样做不是通过采用每个44100/8 = 5512,5样本并保存在新阵列中。但是通过获取前5512个样本的平均值,将新数组保存到原位1。然后取样本5513-11024,这个值的平均值并保存在新数组的第2位。依此类推......将样本11025转换为11025 + 5512并将其平均值放在数组的第3位。
我知道它必须是某种双循环,但我无法弄清楚如何...任何帮助?
编辑:
以非常手动的方式执行我正在寻找的代码。
`fs = 44100;
FO = 8;
A = randn(44100,1);使用随机数据
A_resampled = zeros(numel(A)/5512);
first_block = zeros(5512,1);
for i = 1:length(first_block)
first_block(i) = A(i);
end
first_mean_value = mean(first_block);
A_resampled(1) = first_mean_value;
second_block = zeros(5512,1);
for k = 5513:5512+length(second_block)
second_block(k) = A(k);
end
second_mean_value = mean(second_block);
A_resampled(2) = second_mean_value;`
依旧......
答案 0 :(得分:2)
sampling = 1:5512:length(sample);
resampled = zeros(numel(sampling),1);
for ii = 1:length(sampling)-1
resampled(ii,1) = mean(sampling(ii:ii+1));
end
sampling
是一个带有索引的数组,用于开始采样,然后循环只取所有这些位的平均值。
答案 1 :(得分:2)
reshape
将数组转换为2D矩阵,然后沿列找到mean
。为了确保我们能够正确地执行此操作,我们将填充数组的末尾,以便我们确保您的信号是fs/fo
的整数倍,其中fs
是采样频率并且fo
是所需频率...因此分别为44.1 kHz
和8 Hz
。
因此,假设您的信号存储在A
中,请执行以下操作:
%// Defines
A = ....; %// Define your array here
fs = 44100; %// Sampling frequency
fo = 8; %// Desired frequency
%// Determine how many samples there are per chunk
samples_per_chunk = floor(fs/fo);
%// Determine how many total chunks there are
num_chunks = ceil(numel(A)/samples_per_chunk);
%// Create a padded array where it is an integer multiple
%// of the chunk size and insert the original array into this padded
%// array
Apad = zeros(samples_per_chunk*num_chunks,1);
Apad(1:numel(A)) = A;
%// Reshape into 2D matrix
M = reshape(Apad, [], num_chunks);
%// Find average per chunk
out = mean(M, 1);
然而,这样做的结果是,如果你的数组不是fs/fo
的整数倍,你将不必要地平均一堆附加到数组末尾的零。如果您不希望这种情况发生,一种方法是创建一个最初用NaN
填充的矩阵,并改为使用nanmean
,以便不包含任何NaN
的值在平均值...因此有效地忽略了填充值。
这样的事情会起作用:
%// Code as before..
%// ...
%// ...
%// New
Apad = nan(samples_per_chunk*num_chunks,1);
Apad(1:numel(A)) = A;
M = reshape(Apad, [], num_chunks);
out = nanmean(M, 1);
但是,nanmean
需要统计工具箱。如果您没有这个,那么您可以自己实施nanmean
。将数组重新整形为矩阵M
后,计算每列有多少NaN
个元素,并通过将所有列相加并除以不是的总条目数来计算平均值。 NaN
。
%// Code as before...
%//....
%//....
%// New
M = reshape(Apad, [], num_chunks);
%// Count how total number of NaN values
counts = sum(isnan(M), 1);
%// Set NaN values to zero to not affect mean
M(isnan(M)) = 0;
%// Calculate new average
out = sum(M,2) ./ (size(M,1) - counts);
答案 2 :(得分:2)
如何使用accumarray
?让x
表示您的输入向量。然后
n = ceil((1:numel(x))/5512.5); %// blocks of 5512, 5513, 5512, 5513... samples
result = accumarray(n(:), x (:), [], @mean);
请注意,n
会自动定义不相等的块大小,最多只有一个样本,以匹配小数目标块大小。在您的示例中,块大小为5512
,5513
,5512
,5513
...