gpt4 book ai didi

matlab - 如何确定最后一个的平均值matlab矩阵每列100个非零数

转载 作者:太空宇宙 更新时间:2023-11-03 20:33:36 29 4
gpt4 key购买 nike

我想计算最后一个的平均值,例如matlab中矩阵的每一列中的3个非零数字。这些列的末尾用零填充以创建相同长度的向量。

示例矩阵:

A = [5 6 3 5 6 8 9;
1 2 3 5 4 7 6;
0 1 2 3 4 5 6;
0 0 1 2 3 4 5;
0 0 0 1 2 3 4;
0 0 0 0 2 3 4;
0 0 0 0 2 3 4;
0 0 0 0 0 0 3]

最佳答案

可能有更有效的解决方案,但一种方法是使用 sum 来查找给定列中非零行的数量。然后通过使用 arrayfun 遍历所有列并对列中零之前的 N 行进行平均来获取 A 的平均值。

%// Number of elements to average
N = 3;

%// Last non-zero row in each column
lastrow = sum(A ~= 0, 1);

%// Ensure that we don't have any indices less than 1
startrow = max(lastrow - N + 1, 1);

%// Compute the mean for each column using the specified rows
means = arrayfun(@(k)mean(A(startrow(k):lastrow(k),k)), 1:size(A, 2));

示例

对于您的示例数据,这将产生:

3.0000    3.0000    2.0000    2.0000    2.0000    3.0000    3.6667

更新:另一种选择

另一种方法是使用卷积来实际为您解决这个问题。您可以使用卷积核计算均值。如果您想要一个矩阵的所有 3 行组合的平均值,您的内核将是:

kernel = [1; 1; 1] ./ 3;

当与感兴趣的矩阵进行卷积时,这将计算输入矩阵中所有 3 行组合的平均值。

B = [1 2 3;
4 5 6;
7 8 9];

conv2(B, kernel)

0.3333 0.6667 1.0000
1.6667 2.3333 3.0000
4.0000 5.0000 6.0000
3.6667 4.3333 5.0000
2.3333 2.6667 3.0000

在下面的示例中,我执行此操作然后仅返回我们关心的区域的值(其中平均值仅由每列中的最后一个 N 非零值组成)

%// Find the last non-zero entry in each column
lastrow = sum(A ~= 0, 1);

%// Use convolution to compute the mean for every N rows
%// This will be applied to ALL of A
convmean = conv2(A, ones(N, 1)./N);

%// Select only the means that we care about
%// Because of the padding of CONV2, these will live at the rows
%// stored in LASTROW
means = convmean(sub2ind(size(convmean), lastrow, 1:size(A, 2)));

%// Now correct for cases where fewer than N samples were averaged
means = (means * N) ./ min(lastrow, N);

同样,输出是一样的

3.0000    3.0000    2.0000    2.0000    2.0000    3.0000    3.6667

比较

我运行了一个快速测试脚本来比较这两种方法的性能。很明显,基于卷积的方法要快得多。

enter image description here

这是完整的测试脚本。

function benchmark()
dims = round(linspace(1, 1000, 100));

times1 = zeros(size(dims));
times2 = zeros(size(dims));

N = 3;

for k = 1:numel(dims)
A = triu(rand(dims(k)));
times1(k) = timeit(@()test_arrayfun(N, A));
A = triu(rand(dims(k)));
times2(k) = timeit(@()test_convolution(N, A));
end

figure;
plot(dims, times1);
hold on
plot(dims, times2);

legend({'arrayfun', 'convolution'})
xlabel('Dimension of A')
ylabel('Execution Time (seconds)')
end

function test_arrayfun(N, A)
%// Last non-zero row in each column
lastrow = sum(A ~= 0, 1);

%// Ensure that we don't have any indices less than 1
startrow = max(lastrow - N + 1, 1);

%// Compute the mean for each column using the specified rows
means = arrayfun(@(k)mean(A(startrow(k):lastrow(k),k)), 1:size(A, 2));
end

function test_convolution(N, A)
%// Find the last non-zero entry in each column
lastrow = sum(A ~= 0, 1);

%// Use convolution to compute the mean for every N rows
%// This will be applied to ALL of A
convmean = conv2(A, ones(N, 1)./N);

%// Select only the means that we care about
%// Because of the padding of CONV2, these will live at the rows
%// stored in LASTROW
means = convmean(sub2ind(size(convmean), lastrow, 1:size(A, 2)));

%// Now correct for cases where fewer than N samples were averaged
means = (means * N) ./ min(lastrow, N);
end

关于matlab - 如何确定最后一个的平均值matlab矩阵每列100个非零数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36288101/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com