【问题标题】:How to fill a zeros 3D array with a random number of ones specified in a 2D matrix?如何用 2D 矩阵中指定的随机数填充零 3D 数组?
【发布时间】:2020-10-06 16:21:50
【问题描述】:

3D 数组 A 的大小为 MxNxP。 二维矩阵 B 的大小为 MxN。 对于 B 的每一行,最多有一个大于零的元素。 示例:

B = [0 3 0; 2 0 0];
A = zeros(2,3,4);

我想随机填充 A,使其在第一行和第二列中恰好有三个,在第二行和第一列中恰好有两个。例如:

A(:,:,1) = [0 1 0; 0 0 0]
A(:,:,2) = [0 1 0; 1 0 0]
A(:,:,3) = [0 0 0; 1 0 0]
A(:,:,4) = [0 1 0; 0 0 0]

换句话说,B 元素表示在 A 的第三维中应该有多少个具有相同行和列索引的元素。 我目前可以使用循环来完成,但我期待以更有效的方式进行,因此没有循环,因为 M 和 N 在实践中非常大。 这是我的代码:

B = [0 3 0; 2 0 0];
A = zeros(2,3,4);
for i = 1:size(B,1)
    [r,c] = max(B(i,:));
    idx = randperm(size(A,3),r);
    A(i,c,idx) = 1;
end

【问题讨论】:

  • 这里“更高效”的指标是什么?代码很慢,还是你只想要少于 6 行?循环本身并不慢...
  • 是的,代码很慢,因为 M 真的很大。这就是为什么我要求一个“更高效”的解决方案,这意味着我想要一个充分利用 MATLAB 矩阵操作的解决方案

标签: matlab multidimensional-array


【解决方案1】:

请参阅此答案底部的基准,以解决计算时间方面的“效率”问题。

您可以加快索引循环

通过使用find,您可以获得B 非零的实际索引,这使得循环更具“针对性”,然后您可以跳过对max 的调用,因为我们不关心B 的整行。

这也可以说更加灵活,因为它不对B 的每一行中非零值的数量进行任何限制。

[M, N] = size(B);
% Set up the output
A = zeros(M,N,P);
% Get row and column indices of non-zero B
[r,c] = find(B);
for ii = 1:numel(r)
    % Index into A, given row and column, random columns according to B
    A( r(ii), c(ii), randperm( P, B(r(ii), c(ii)) ) ) = 1;
end

全矩阵运算不一定很快。 下面的操作没有使用循环,但是内存效率确实很低,这使得大输入速度很慢!

  1. 创建一个随机矩阵

    r = rand( M, N, P );
    
  2. 对第三维的随机随机矩阵进行排序,我们不关心排序后的矩阵,只关心索引;即排序。这是一种获取整个矩阵的方法,其中进入第 3 维的每个向量都包含 1:P 打乱(类似于在循环中使用 randperm)。

    [~,shuff] = sort(r, 3);
    
  3. 使用B 作为阈值,将洗牌后的索引转换为1/0。请注意,这使用隐式扩展,这需要 MATLAB 2016b 或更高版本。

    A = (shuff <= B)
    

你可以将 1. 和 2. 合并为一个步骤,那么完整的代码就变成了

% Inputs
B = [0 3 0; 2 0 0];
P = 4;
% Get shuffled matrix
[M, N] = size(B);
[~,shuff] = sort( rand( M, N, P ), 3 );
% Get ouput
A = (shuff <= B);

基准测试

我们可以运行一个快速基准来比较这些方法。在非常小的一端,矩阵运算更快。对于大型B,此答案顶部提出的有效循环要快得多。

此基准测试使用N = 7, P = 10, M = variable,因为您说实际上您的M 很大。

【讨论】:

    猜你喜欢
    • 2012-03-06
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多