Matlabで質問がありました。そうです、私は列の異なる数の値の平均を取ろうとします。たとえば、以下の列がある場合、
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5]
まず、5 つの値の平均を取り、それらをプロットすることから始めたいと思います。上記の場合、プロットできる 3 つの平均を受け取る必要があります。次に、一度に 10 個の値を取得します。それを修正するためにカスタムコードを書く必要があるのだろうか。
これでうまくいくはずです:
選択したN
(平均を取りたい値の数) の場合:
N = 5;
mean_vals = arrayfun(@(n) mean(X(n-1+(1:N))),1:N:length(X))
注: これはIndex exceeds matrix dimensions
.
最後の数字をスキップしたい場合、これはうまくいくはずです:
mean_vals = arrayfun(@(n) mean(X(n-1+(1:N))),1:N:(length(X)-mod(length(X),N)));
残りの値を追加するには:
if mod(length(X),N) ~= 0
mean_vals(end+1) = mean(X(numel(X)+1-mod(length(X),N):end))
end
更新:これはEitan の最初の回答 (編集前) の修正です。nanmean()
ではないすべての値の平均を取る を使用しますNaN
。したがって、残りの行をzeros
で埋める代わりに、 で埋めてNaN
、平均を取ります。
X = [X(:); NaN(mod(N - numel(X), N), 1)];
X_avg = nanmean(reshape(X, N, []));
おそらく最速の方法は、初期ベクトルX
をいくつかの行列に再配置し、各列に必要な値を平均して格納することです。
A = reshape(X, N, []);
ここN
で、 は新しい行列の目的の行数です。空の括弧 ( []
) は、列数を自動的に計算するように MATLAB に指示します。次に、次を使用して各列を平均化できますmean
。
X_avg = mean(A);
ベクトルX_avg
は結果を格納します。これは次のように 1 行で実行できます。
X_avg = mean(reshape(X, N, []));
の要素数はX
で割り切れる必要があることに注意してくださいN
。そうでない場合は、最初にパディングするか (たとえばゼロで)、「残りの」末尾要素を個別に処理する必要があります。
tail = mod(numel(X), N);
X_avg = mean(reshape(X(1:numel(X) - tail), N, [])); %// Compute average values
X_avg(end + 1) = mean(X(end - tail + 1:end)); %// Handle leftover elements
後でこのコードをループに入れて、N
反復ごとに の異なる値の平均値を計算してプロットすることができます。
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5];
N = 5;
tail = mod(numel(X), N);
X_avg = mean(reshape(X(1:numel(X) - tail), N, []))
X_avg(end + 1) = mean(X(end - tail + 1:end))
結果は次のとおりです。
X_avg =
2.2000 3.4000 6.0000
別の例を次に示します (この場合、 の長さはX
で割り切れませんN
)。
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5];
N = 10;
tail = mod(numel(X), N);
X_avg = mean(reshape(X(1:numel(X) - tail), N, []))
X_avg(end + 1) = mean(X(end - tail + 1:end))
結果は次のとおりです。
X_avg =
2.8000 6.0000
この操作を頻繁に行う必要がある場合は、独自の関数を作成する価値があるかもしれません。@EitanT の基本的なアイデアを使用することをお勧めします。データをパディングし、形状を変更し、各列を平均します。ただし、最後にゼロが埋め込まれた数値を含めるのではなく、「散らばった」データポイントの平均を個別に取得することをお勧めします。
function m = meanOfN(x, N)
% function m = meanOfN(x, N)
% create groups of N elements of vector x
% and return their mean
% if numel(x) is not a multiple of N, the last value returned
% will be for fewer than N elements
Nf = N * floor( numel( x ) / N ); % largest multiple of N <= length of x
xr = reshape( x( 1:Nf ), N, []);
m = mean(xr);
if Nf < N
m = [m mean( x( Nf + 1:end ) )];
end
この関数は、まさにあなたが求めていたものを返します: N=5 の 15 要素ベクトルの場合、3 つの値を返します。入力ベクトルのサイズが N の倍数でない場合、返される最後の値は「残りの平均」になります。
多くの場合、一連の数値の平均を取る必要がある場合、関心のあるのは「移動平均」です。[mean(x(1:5)) mean(x(6:10)) mean(11:15))]
したがって、 を取得するのではなく、
m(1) = mean(x(1:N));
m(2) = mean(x(2:N+1));
m(3) = mean(x(3:N+2));
...etc
これは、データと 1 のベクトルの単純な畳み込みを使用して実現できます。完全を期すために、可能なコーディング方法を次に示します。
function m = meansOfN(x, n)
% function m = meansOfN(x, n)
% taking the running mean of the values in x
% over n samples. Returns a row vector of size (sizeof(x) - n + 1)
% if numel(x) < n, this returns an empty matrix
mv = ones(N,1) / N; % vector of ones, normalized
m = convn(x(:), mv, 'valid'); % perform 1D convolution
これら 2 つの関数をパスに配置するmeanOfN.m
と(meansOfN.m
それぞれ と という名前のファイルに保存されます)、必要なことは何でも実行できます。どのプログラムでも、あなたは書くことができます
myMeans = meanOfN(1:30, 5);
myMeans2 = meansOfN(1:30, 6);
など。Matlab は関数を見つけ、計算を実行し、結果を返します。このような特定の操作用のカスタム関数を作成すると、非常に役立ちます。コードをクリーンに保つだけでなく、関数を 1 回テストするだけで済みます...
いくつかのコードを投稿し、何が機能していないかを正確に指摘していただけると助かります。
最初のポインタとして。もしも
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5]
あなたが興味を持っている5つのブロックの3つの手段は
mean(X(1:5))
mean(X(6:10))
mean(X(11:15))
for ループを考え出すか、インデックスを反復処理する他の方法を考え出す必要があります。
私はあなたがこのようなものが欲しいと思います (私はしばらくMatlabを使用していませんでした.構文が正しいことを願っています):
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5],
currentAmount=5,
block=0,
while(numel(X)<=currentAmount)
while(numel(X)<=currentAmount+block*currentAmount)
mean(X(block*currentAmount+1:block*currentAmount+currentAmount));
block =block+1;
end;
currentAmount = currentAmount+5;
block=0;
end
このコードは、一度に 5 つの要素の平均を計算するすべての要素を最初にループします。その後、10 要素に展開されます。それから 15 まで、というように、平均を作成する要素の数が列の要素の数よりも大きくなるまで続けます。