【问题标题】:Concatenate every n-th row连接每第 n 行
【发布时间】:2013-05-08 10:08:03
【问题描述】:

我得到了一个矩阵中的数据集,如下所示(从 Excel 导入):

matrix =
    Cat1   1  2  3  4
    Cat2   9 10 11 12
    Cat3  17 18 19 20
    Cat1   5  6  7  8
    Cat2  13 14 15 16
    Cat3  21 22 23 24

我想将其重塑为 3 个相同大小的向量(每个类别一个)来绘制堆积条形图。向量在 reshape 操作后应该是这样的(如果向量具有第一列的名称并且矩阵可以是任意大小,那就太好了):

cat1 = [ 1  2  3  4  5  6  7  8]
cat2 = [ 9 10 11 12 13 14 15 16]
cat3 = [17 18 19 20 21 22 23 24]

我真诚地希望这不是重复的。在其他重塑问题的帮助下,我无法提出可行的解决方案。

【问题讨论】:

  • Cat1; Cat2... 等是您矩阵的一列,还是这些类别肯定每 n 行重复一次?
  • matrix 的类型是什么?元胞数组、数据集对象、..?
  • @Dan 您的假设是正确的。 @ Amro 我将数据导入为元胞数组,因为矩阵选项将用 NaN 替换我的文本值。老实说,我不知道数据集类型的作用。

标签: matlab vector matrix


【解决方案1】:

如果你的数据是一个矩阵,你可以在索引时操纵行的顺序,所以你可以这样做:

rows = reshape(1:size(matrix, 1), n, []).';
res = reshape(matrix(rows, :).', [], n).';

生成的矩阵res 由串联的行组成。

此解决方案也适用于元胞数组,但您需要额外的 cell2mat 才能将结果转换为矩阵。

示例

matrix = [1:4; 9:12; 17:20; 5:8; 13:16; 21:24];
n = 3;

rows = reshape(1:size(matrix, 1), n, []).';
res = reshape(matrix(rows, :).', [], n).';

结果是:

res =
     1     2     3     4     5     6     7     8
     9    10    11    12    13    14    15    16
    17    18    19    20    21    22    23    24

【讨论】:

  • 我已经测试了你的代码并且它可以工作。谢谢你。我现在已经导入了不带标题的数据(cat1、cat2、...)。
  • @Sensei 太棒了。请考虑通过单击投票按钮旁边的复选标记 (✓) 将此问题标记为已接受。
  • 当然。我有几个关于 Amro 提供的解决方案的问题。我还应该接受你的回答吗?
  • @Sensei 您应该接受对您最有帮助的答案,以表明其他用户正在寻求类似问题的答案。慢慢来:)
【解决方案2】:

编辑:

尝试以下方法:

%# dataset stored in a cell array
data = {
    'Cat1'   1  2  3  4
    'Cat2'   9 10 11 12
    'Cat3'  17 18 19 20
    'Cat1'   5  6  7  8
    'Cat2'  13 14 15 16
    'Cat3'  21 22 23 24
};

%# get all possible values of first column,
%# and map them to integer indices
[L,~,IDX] = unique(data(:,1));

%# for each possible "category"
groups = cell(max(IDX),1);
for i=1:max(IDX)
    %# get the rows of numeric data matching current category
    M = data(IDX==i, 2:end)';

    %# flatten matrix into a vector and store in cell (row-major order)
    groups{i} = [M{:}];
end

现在您可以通过以下方式访问第 i 个“猫”向量:groups{i}

>> [cat1,cat2,cat3] = deal(groups{:})
cat1 =
     1     2     3     4     5     6     7     8
cat2 =
     9    10    11    12    13    14    15    16
cat3 =
    17    18    19    20    21    22    23    24

请注意,匹配的“猫”标签存储在L{i}(映射键)中

【讨论】:

  • 而不是使用data(:,1) 作为ismember 的第一个参数,我认为如果你使用L{i} 其中L = unique(data(:,1)); 会更通用。 length(L) 应该等于 numel(groups)
  • @Sensei ismember 查找原始数据中的哪些行具有相同的 'Cat' 字符串,然后将它们提取到新的单元格数组 M 中,连接在一起并存储在适当的单元格中在groups.
  • @Amro 当您使用它时,您应该考虑在 'Cat' 字符串上应用 'unique',而不是预先分配具有预定大小的 groups。但是,问题的标题是“每 n 行”,我认为使用“Cat”字符串是一种矫枉过正。
  • @Sensei 是的,你可以。例如,从第一行中提取第三个值groups{1}{3}
  • @Sensei 和其他人:谢谢,我实施了您的建议。我在每一步都添加了更多的 cmets。
猜你喜欢
  • 2017-07-26
  • 2020-03-01
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
  • 2022-11-15
  • 2017-09-13
  • 2021-03-28
  • 2021-04-22
相关资源
最近更新 更多