【问题标题】:Given a row vector, how do I create an indicator matrix placing each value in its respective column location?给定一个行向量,如何创建一个指示矩阵,将每个值放置在其各自的列位置?
【发布时间】:2015-05-10 16:37:46
【问题描述】:

为了深入了解上面的标题,我有一个向量定义如下:

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

鉴于上述向量,我如何在 MATLAB 中创建此矩阵?

1 1 1 1 1 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 2 2 2 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 3 3 3 3 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 4 4 4

基本上,对于A 的每个唯一值,都有一个与之关联的行。对于每一行,与感兴趣的特定值相等的位置被放置在它们各自的列中。

在 MATLAB 中最有效的方法是什么?

【问题讨论】:

  • 您应该发布您对此问题所做的任何研究。另外,你实际尝试了什么。请阅读How do I ask a good question?
  • 考虑查看stackoverflow.com/tour 以了解 SO 的工作原理
  • 我试过谷歌但什么也找不到。我不知道我会使用哪个关键字来搜索
  • 我同意 OP 应该展示他/她所做的事情,但这个问题对我来说似乎很合适。
  • 我同意这个问题没有任何努力,但这是一个有趣的问题,我也提供了答案。顺便说一句,您在 Google 上找不到这个,因为它是一个具有自定义行为的矩阵。 IIRC,MATLAB 中没有内置的函数可以做你想做的事情,所以在这里问这个问题是一个不错的决定。

标签: matlab matrix


【解决方案1】:

另一种方法是通过bsxfununique。假设A 是一个行向量,您将执行以下操作:

un = unique(A.', 'stable');
out = bsxfun(@times, bsxfun(@eq, A, un), un);

out 包含您想要的结果。这段代码值得解释一下。第一行代码确定存储在un 中的A 中的所有唯一条目,但以stable 的顺序或遇到它们的顺序提供它们。不这样做也会对值进行排序。我认为值从 1 到 4 的情况是一个简化的示例,您希望对任意顺序的数字执行此操作,并且它们也出现在向量中的任何位置。

第二行代码其实相当优雅。让我们从嵌套在其中的第一个 bsxfun 调用开始:

bsxfun(@eq, A, un)

bsxfun 是一个非常好的函数,可以在单维维度上广播。这对我们的例子意味着A 是一个行向量,un 是一个列向量,这将产生一个 ma​​trix,我们可以在其中找到元素方面的 equality 两个矩阵 - 一个矩阵复制A 的行向量,其元素数量与un 中的元素一样多,另一个矩阵复制列向量的元素数量与A 中的元素数量相同。其结果是一个矩阵,其中每一行告诉您A 中的哪些位置与un 中的特定值匹配,从un 的开头(第一行)到un 的结尾(最后一行)。最后一部分是获取这个等式矩阵并使用另一个bsxfun 调用与un 进行元素乘法,以便un 再次按列广播自己,就像在bsxfun(@eq, A, un) 中所做的那样。结果是将每行不等于所表示的un 中的相应值的确切位置归零,因此我们得到了结果。

示例

>> A = [1 1 1 1 1 2 2 2 3 3 3 4 4 4]

A =

  Columns 1 through 13

     1     1     1     1     1     2     2     2     3     3     3     4     4

  Column 14

     4

调用上面的代码给我们:

>> out

out =

  Columns 1 through 13

     1     1     1     1     1     0     0     0     0     0     0     0     0
     0     0     0     0     0     2     2     2     0     0     0     0     0
     0     0     0     0     0     0     0     0     3     3     3     0     0
     0     0     0     0     0     0     0     0     0     0     0     4     4

  Column 14

     0
     0
     0
     4

【讨论】:

  • 非常好的和完整的答案,像往常一样!我觉得 OP 对 Matlab 不是很有信心,所以我不会使用 bsxfun,在我看来,这是为更有经验的用户准备的。
  • @Ratbert - 谢谢 :) 完全理解 :)... 但是,学习永远不会太晚! FWIW,我只是在开始回答 StackOverflow 问题后才对 bsxfun 感到满意。在我看到 Divakar 经常使用它之前,我什至不知道这个功能的存在。
  • @ILIKEANN - 没问题。祝你好运!
【解决方案2】:

您可以为此使用sparse

result = full(sparse(A, 1:numel(A), A));

或者将结果矩阵初始化为零,然后使用sub2ind在适当的位置填写A

m = max(A);
n = numel(A);
result = zeros(m, n);
result(sub2ind([m n], A, 1:numel(A))) = A;

【讨论】:

  • 嘿! sparse 的有趣方法。
  • @rayryeng 谢谢!我添加了另一个,基于sub2ind。但我更喜欢sparse
  • sub2ind 我更喜欢它,因为它让你真正跳出框框思考,但其中任何一种方法对我来说都很好:)
【解决方案3】:

假设你的初始数组是A:

for i=1:4
    B=A;
    B(B~=i) = 0;
    disp(B);
end

中间的棘手命令替换了B 中不等于i 的所有内容。

最好的,

【讨论】:

  • 良好的规范方法。可能和bsxfun / unique 一样快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
相关资源
最近更新 更多