通过计算MATLAB中的平均值进行下采样

时间:2015-09-29 16:26:18

标签: matlab for-loop

假设我有一个包含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);使用随机数据在fs = 44100处采样的%数组

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;`

依旧......

3 个答案:

答案 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 kHz8 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会自动定义不相等的块大小,最多只有一个样本,以匹配小数目标块大小。在您的示例中,块大小为5512551355125513 ...