如何使用第一列作为索引从单个矩阵创建矩阵数组?

Posted

技术标签:

【中文标题】如何使用第一列作为索引从单个矩阵创建矩阵数组?【英文标题】:How can I create an array of matrices from a single matrix by using first column as index? 【发布时间】:2017-03-19 15:04:47 【问题描述】:

假设,我有以下矩阵,

1   2   3   4   5   6   7   8
2   3   4   5   6   7   8   1 
3   4   5   6   7   8   1   2 
4   5   6   7   8   1   2   3
1   8   7   6   5   4   3   2
2   7   6   5   4   3   2   9
3   6   5   4   3   2   9   8 
4   5   4   3   2   9   8   7

我想创建一个由 4 个矩阵组成的数组,按照列 #1 进行分类。

例如,输出应该如下所示,

[ 
  2 3 4 5 6 7 8
  8 7 6 5 4 3 2

  3 4 5 6 7 8 1
  7 6 5 4 3 2 9 

  4 5 6 7 8 1 2
  6 5 4 3 2 9 8

  5 6 7 8 1 2 3
  5 4 3 2 9 8 7 
] 

我的目标是将this Parzen function 应用于他们每个人。


是不是像下面这样?

function [retval] = bayes (train, test)

    classCounts = rows(unique(train(:,1)));
    pdfmx = ones(rows(test), classCounts);

    variance = 0.25;
    pdf = parzen(train(:,2:end), test(:,2:end), variance);

    for cl=1:classCounts
        clidx = train(:,1) == cl;
        mu(:,cl) = train(clidx,2:end);      
    end
    retval = mu;
endfunction

此代码正在生成以下错误,

>> bayes(mat, mat)
error: bayes: A(I,J,...) = X: dimensions mismatch
error: called from
    bayes at line 11 column 12
>>

【问题讨论】:

【参考方案1】:

这是accumarray 的经典工作。它输出一个元胞数组,但我建议您继续使用 3D 矩阵。

%// data
A = [1   2   3   4   5   6   7   8
     2   3   4   5   6   7   8   1 
     3   4   5   6   7   8   1   2 
     4   5   6   7   8   1   2   3
     1   8   7   6   5   4   3   2
     2   7   6   5   4   3   2   9
     3   6   5   4   3   2   9   8 
     4   5   4   3   2   9   8   7]

%// input
groupid = A(:,1);      %// group identifier
rowidx = 1:size(A,1);  %// row index

%// accumarray
cellArray = accumarray(groupid(:),rowidx (:),[],@(x) A(x,2:end))

%// transform cell array to 3D-Matrix
threeDArray = cat(3,cellArray:)

说明

accumarray 是什么?

它将vals = rowidx 的所有元素与相同的subs = groupid 组合起来并执行操作。 由于您想对矩阵的行而不是单个向量执行操作,但需要向量输入,您可以通过实际引入行索引作为输入来“欺骗”accumarray,而不是在函数中使用 apply A(x,2:end) 表示您将所有rowidx 与存储在x 中的相同groupid 一起使用,并使用它来访问您的矩阵A,您将 放在周围以获得单元格数组输出
cellArray1 =
     8     7     6     5     4     3     2
     2     3     4     5     6     7     8
cellArray2 =
     7     6     5     4     3     2     9
     3     4     5     6     7     8     1
cellArray3 =
     6     5     4     3     2     9     8
     4     5     6     7     8     1     2 
cellArray4 =
     5     4     3     2     9     8     7
     5     6     7     8     1     2     3

threeDArray(:,:,1) =
     8     7     6     5     4     3     2
     2     3     4     5     6     7     8  
threeDArray(:,:,2) =
     7     6     5     4     3     2     9
     3     4     5     6     7     8     1
threeDArray(:,:,3) =
     6     5     4     3     2     9     8
     4     5     6     7     8     1     2
threeDArray(:,:,4) =
     5     4     3     2     9     8     7
     5     6     7     8     1     2     3

如果输出中的行顺序很重要,则需要accumarray 的“稳定版本”(受this answer 启发:

%// stabilize accumarray
sz = max(groupid,[],1);
[~, I] = sort(groupid*cumprod([1,sz(1:end-1)]).');

%// stable accumarray
cellArray = accumarray(groupid(I,:),rowidx(I),[],@(x) A(x,2:end))

cellArray1 =
     2     3     4     5     6     7     8
     8     7     6     5     4     3     2
cellArray2 =
     3     4     5     6     7     8     1
     7     6     5     4     3     2     9
cellArray3 =
     4     5     6     7     8     1     2
     6     5     4     3     2     9     8
cellArray4 =
     5     6     7     8     1     2     3
     5     4     3     2     9     8     7

threeDArray(:,:,1) =
     2     3     4     5     6     7     8
     8     7     6     5     4     3     2
threeDArray(:,:,2) =
     3     4     5     6     7     8     1
     7     6     5     4     3     2     9
threeDArray(:,:,3) =
     4     5     6     7     8     1     2
     6     5     4     3     2     9     8
threeDArray(:,:,4) =
     5     6     7     8     1     2     3
     5     4     3     2     9     8     7

【讨论】:

cellArray = accumarray(subs(:),vals(:),[],@(x) A(x,2:end)) 这很难理解。 @anonymous 看看我的编辑,连同文档,现在应该更清楚了

以上是关于如何使用第一列作为索引从单个矩阵创建矩阵数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在熊猫中设置第一列和第一行作为索引?

使用pandas创建稀疏矩阵,并使用来自.dat文件的其他两列的索引[x,y]的.dat文件的一列中的值填充它

如何从python中的数组(或矩阵)中提取除一列之外的所有列?

在R中如何输出矩阵,第一列和第二列的数为指定数字

matlab中如何给已有矩阵插入一行或一列值

矩阵倒置