【问题标题】:How to divide vector to subvectors based on another vector in matlab如何根据matlab中的另一个向量将向量划分为子向量
【发布时间】:2015-08-20 17:57:04
【问题描述】:

我有一个向量,假设它是 b=[1 2 2 3 4 1 2 1 4...] 和另一个向量 A(n),我想按以下方式划分向量:

A(1)A(6)A(8) 都属于向量 1,称为 Av1 A(2)A(6)A(8) 都属于称为 Av2 的向量 2 等等……

向量 b 可以有 1:n 的数字,这意味着我不能为每个 Av 单独编写代码。基本上每个 b(i) 对应于每个 A(i) 并告诉我它将属于哪个子向量。有人知道吗?

提前谢谢你!

【问题讨论】:

  • 好吧...您的目标是为向量b 中的每个i 提取i 的值吗?例如,您的第一个输出将是一个包含 3 个 1 的数组,下一个输出包含一个包含 3 个 2 的数组,等等......或者您是否要提取每个 @ 值的 位置 987654332@是?你的问题描述不清楚
  • 不是 3 个 1,我的第一个向量将由 A(1)、A(6) 和 A(8) 的内容组成

标签: matlab vector


【解决方案1】:

首先,我不建议您为每个数组创建单独的变量...这会很笨拙。如果b 中有 100 个不同的值怎么办?我建议您使用cell 数组,而不是每个单元格提取出A 的相应值。

简单地调用arrayfununique 就足够了:

out = arrayfun(@(x) A(b == x), unique(b), 'uni', 0);

对于b 中的每个唯一值,我们会提取A 中匹配的相应位置并将它们放入一个单元格数组中。鉴于你的小例子:

b=[1 2 2 3 4 1 2 1 4];

.... 和A 很简单:

A = 1:numel(b);

我故意这样声明A,以便它与您正在提取的A 的实际对应位置相匹配……因此A(i) = ii = 1 的值与b 的值一样多。

我们得到这个:

>> celldisp(out)

out{1} =

     1     6     8



out{2} =

     2     3     7



out{3} =

     4



out{4} =

     5     9

您可以看到,对于每个单元格,我们在A 中提取出与b 中找到的每个唯一ID 相对应的正确值。


如果您不熟悉arrayfun,它基本上对输入数组的每个值执行一个函数。在我们的例子中,我想做的是指定一个数组作为b 中的所有唯一值。对于b 中的每个唯一值,我会查看在哪里可以找到这些匹配的位置,然后使用逻辑索引来提取A 中的对应值。

arrayfun 基本上是一个for 循环,因此等效的for 循环代码将如下所示:

unq = unique(b);
out = cell(1,numel(unq));
for idx = 1:numel(unq)
    x = unq(idx);
    out{idx} = A(b == x);
end

我们首先找到b中的所有唯一值并将它们存储在unq中,创建一个具有与唯一值一样多的单元格的单元格数组,然后为每个唯一值提取正确的@987654352 @ 值与b 中的给定i 值匹配。

【讨论】:

  • 完美运行!现在我必须了解 arrayfun 是如何工作的!谢谢!
  • @System - Oh :) arrayfun 对数组的每个元素执行一个函数。这基本上是一个for 循环。我将编辑我的帖子,以便您可以看到它使用 for 循环。
  • @System - 看看我的编辑。它解释了arrayfun 的工作原理,以及如果你想使用循环来代替,你会如何做。
【解决方案2】:

作为@rayryeng says,不要创建单独的变量;改用cell array。您可以使用accumarray 执行此操作,如下所示:

首先定义你的数据:

b = [ 1 2 2 3 4 1 2 1 4 ];
A = 1:numel(b); %// for example

然后

C = accumarray(b(:), A(:), [], @(x) {x});

给予

>> C
C = 
    [3x1 double]
    [3x1 double]
    [         4]
    [2x1 double]
>> celldisp(C)
C{1} =
     6
     8
     1
C{2} =
     7
     3
     2
    C{3} =
     4
C{4} =
     5
     9

如果你想保持原来的顺序:

[bs, ind] = sort(b);
As = A(ind);
C = accumarray(bs(:), As(:), [], @(x) {x});

给予

>> C
C = 
    [3x1 double]
    [3x1 double]
    [         4]
    [2x1 double]
>> celldisp(C)
C{1} =
     1
     6
     8
C{2} =
     2
     3
     7
C{3} =
     4
C{4} =
     5
     9

【讨论】:

  • 啊...应该知道使用accumarray,但是是的,需要sort 来保证顺序,因为数字组合在一起的方式是随机顺序的。非常好的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多