在MatLab中快速将矩阵转换为长格式的矩阵

ehxuflar  于 2022-11-15  发布在  Matlab
关注(0)|答案(1)|浏览(239)

在MatLab中,如何将矩阵转换成长格式
Rthis can be done with functions such as reshape2, or melt中,但在matlab中,我能找到的唯一方法是使用for循环来创建一个新的矩阵。

function wide_to_long(wide_array, save, save_path, precision_fun)
  "Wide to long is started ... for " + save_path
    if nargin == 1
      save = false;
    end
    tic
    n_dims = length(size(wide_array));
    dt_long = precision_fun(zeros(prod((size(wide_array)), 'all' ), n_dims+1));
    if n_dims == 2
        n_rows = size(wide_array,1);
        n_cols = size(wide_array,2);
        all_combinations = combvec(1:n_rows, 1:n_cols);
        parfor (i_comd = 1:size(all_combinations, 2), 3)
            comb = all_combinations(:,i_comd);
            dt_long(i_comd, :) = [comb', wide_array(comb(1), comb(2))];
        end
    end
    toc
    if save == true
        "Saving to " + save_path
        writematrix(dt_long, save_path, 'Delimiter',',');
    end
end

然而,在MatLab中使用循环太慢。节省约7 GB的矩阵至少需要40分钟。
有没有一种方法可以在MatLab中快速地将一个矩阵转换成一个长格式的矩阵?
例如:如果我们有wide_array = [10,20;30,40],则此数组的长格式为

long_array = [1,1,10; 1,2,20;2,1,30; 2,2,40]

在这里,前两个维度标记值在wide_array中的位置,而第三个维度包含存储在原始数组中的值。

ffdz8vbo

ffdz8vbo1#

我想出了以下功能:

function dt_long = wide_to_long(varargin)
  if nargin == 0
      "No input matrix is provided, dude!"
      return
  end
  defaults = {false, "~/output_wide_to_long.csv", @(x) single(x)};
  defaults(1:(nargin-1)) = varargin(2:end);
  wide_array = varargin{1,1};
  save = defaults{1,1};
  save_path = defaults{1,2};
  precision_fun = defaults{1,3};
  
  "Wide to long is started."
  if save == true
      "Save path " + save_path
  end
  
    if nargin == 1
      save = false;
    end
    tic
    n_dims = length(size(wide_array));
    dimensions = size(wide_array);
    indices = {};
    for i = 1:n_dims
        indices{1, i} = 1:dimensions(i);
    end
    all_combinations = combvec(indices{:});
    dt_long = precision_fun([all_combinations', reshape(wide_array, [], 1)]);
    toc
    if save == true
        "Saving to " + save_path
        writematrix(dt_long, save_path, 'Delimiter',',');
    end
end

一个示例用例是

wide_matrix = rand(4,3,2);
wide_to_long(wide_matrix, true, "~/test.csv", @(x) single(x)

就其性能而言,将一个包含1亿个元素的矩阵转换并保存为CSV文件需要大约7秒。

相关问题