矩阵变换

3

我正在进行一个项目,需要将结果矩阵转换成一个更简单的矩阵。更具体地说,对于矩阵中的每一列,我想找到行中的最大值,并将其改为1,其余的值将被改为0。我不确定如何搜索这个问题,所以我决定在这里发帖。

举个例子,我有一个矩阵X:

X = [2 8 4; 7 3 9;1 2 3];
X = 2 8 4
    7 3 9
    1 2 3

我想把这个矩阵转换成

X' = 0 1 0
     1 0 1
     0 0 0

我只知道如何使用for循环从每一行返回最大值,但不确定如何返回该值在矩阵中的位置并将其余部分转换为零。
这是我的想法:
  1. 首先创建一个相同维度的零矩阵
  2. 找到行中的最大值
  3. 找到最大值的位置
  4. 在新矩阵中在相同位置上分配值1
  5. 通过for循环重复步骤2和3
我对Matlab不熟悉,希望你能帮忙。
这是程序的其中一个结果。
 2.0680   17.7410    0.8992   -3.0221
 3.6093    7.3443    6.7442    0.9874
-0.9095   -3.3220   -1.4857   -0.0023
-1.1753  -16.7906    0.3672    3.7697
-1.6856   -6.0929   -2.8614    0.5054
 1.0794    3.8352    1.9894    0.1686
-0.4584   -0.3923   -1.2525   -0.4761

我希望进行这个矩阵变换

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

我觉得max()函数不能正常工作的原因是矩阵中存在负值。
另一个不能使用max()函数的例子: 第1列到第5列。
 0.3816   23.2243   19.6435   23.2243   -3.1993
 3.8674    8.0762    6.0563    8.0762    1.8475
-0.4442   -4.0758   -3.4244   -4.0758    0.2073
 0.7639  -22.3618  -19.1365  -22.3618    3.9892
-1.8128   -6.4602   -5.1011   -6.4602   -0.4536
 0.2954    3.5886    3.1529    3.5886   -0.1403
-0.3723    0.8057    0.6607    0.8057   -0.5173

第5列到第10列。
 1.4814   19.6435    3.3100   23.2243    1.4814
 7.0255    6.0563    6.5251    8.0762    7.0255
-1.1483   -3.4244   -1.1448   -4.0758   -1.1483
-0.7784  -19.1365   -2.3904  -22.3618   -0.7784
-3.8880   -5.1011   -3.7437   -6.4602   -3.8880
 1.0289    3.1529    0.7994    3.5886    1.0289
-0.3723    0.8057    0.6607    0.8057   -0.5173

第11列到第15列
 21.3957   19.6435    1.4814    0.3816   -3.1993
 8.5765    6.0563    7.0255    3.8674    1.8475
-4.0793   -3.4244   -1.1483   -0.4442    0.2073
-20.7498  -19.1365   -0.7784    0.7639    3.9892
-6.6046   -5.1011   -3.8880   -1.8128   -0.4536
 3.8181    3.1529    1.0289    0.2954   -0.1403
 0.4994    0.6607   -0.5829   -0.3723   -0.5173

16到20列

  -1.7736    9.5635   20.0251    1.8072    0.3816
   1.6114    7.0884    9.9237    3.6313    3.8674
  -0.0058   -2.3835   -3.8685   -0.6572   -0.4442
   2.1941   -8.7540  -18.3726   -1.0312    0.7639
  -0.5815   -4.5430   -6.9138   -1.9407   -1.8128
   0.1232    2.4470    3.4483    0.5589    0.2954
  -0.3588   -0.2377    0.2884   -0.2138   -0.3723

正确答案是使用bsxfun(@eq, output, max(output))。

2
你说“每行最大值”,但你展示的是“每列最大值”……你指的是哪个? - Rody Oldenhuis
1
@RodyOldenhuis 抱歉,我犯了一个错误,应该是对于矩阵中的每一列,找到具有最大值的行,将其转换为1,将其余行转换为0。因此应该是列。 - Shawn Lien
2个回答

5
您可以使用 bsxfun 函数来检查一个值是否等于其所在列的最大值。
X = bsxfun(@eq, X, max(X))

请查看我上面链接的文档,了解更多关于bsxfun如何工作的解释和示例。

5
我不是很确定你的意思,但是这句话的意思是:
>> bsxfun(@eq, X, max(X,[],2))  % maximum per row
ans =
     0     1     0
     0     0     1
     0     0     1

靠近?如果你的意思是每个的最大值,那么只需使用:
>> bsxfun(@eq, X, max(X)) % maximum per column
ans =
     0     1     0
     1     0     1
     0     0     0

谢谢,这个方法确实有效。但是在我的实验中,真实矩阵包含非正整数,因此如果使用此方法,Matlab将会持续返回“下标索引必须是实际的正整数或逻辑值”的错误信息。有什么解决这个问题的方法吗? - Shawn Lien
我正在创建一个RBF神经网络,没有使用NN工具箱,我需要将训练输出与目标进行比较。训练输出中的每个单元格都是通过高斯函数计算得出的值,因此这些值始终为双精度值。我需要将输出矩阵转换为我在问题中提到的矩阵,并将其与目标进行比较。我刚刚意识到max()只能在数据全部为整数时起作用,希望这不会造成干扰。 - Shawn Lien
2
Shawn,当一些数据为双精度时,max函数仍然能够正常工作。你可以发布一下在Rody的答案无法正常工作的矩阵吗?同时也请告诉我们你认为该矩阵应有的正确答案是什么? - Dan Becker
@DanBecker 你好,抱歉回复晚了,我已经编辑了我的问题。我认为Rody的方法不起作用的原因是我的矩阵包含负值。 - Shawn Lien
@ShawnLien:在这里,我使用你提供的矩阵的方法可以产生你想要的精确输出... - Rody Oldenhuis
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接