-1

我有一个m x n矩阵,其中每一行由零和每一行的相同值组成。

一个例子是:

M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0]

在此示例中,第一列由0s 和-0.6、第二个01.8、第三个-2.3等组成。

在这种情况下,我想将 m 减少到 1(从给定矩阵中获取一个向量),所以在这个例子中,一个向量将是[-0.6 1.8 -2.3 3.4 -3.8 -4.3]

有谁知道从这样的矩阵中获取向量的最佳方法是什么?

谢谢!

4

5 回答 5

1

如果存在未知数量的非零和零,解决问题的一种方法是首先用 NaN 替换零,然后使用 max 或 min 之类的东西来查找数据。

%# create an array
M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0];

%# replace zeros with NaN
M(M==0) = NaN;

%# get, for each column, the number
numbers = max(M,[],1)

numbers =

    -0.6000    1.8000   -2.3000    3.4000   -3.8000   -4.3000

编辑

这就是我理解这个问题的方式:“我希望对于每一列都知道非零条目的值。每列只有一个非零数字,但它可能会出现多次”

这是一种更类似于 Matlab(但更长)的方法来获得解决方案:

%# create an array
    M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0];

%# find the non-zero entries
[r,c] = find(M);

%# only take one entry per column
[uniqueCols, sortIdx] = unique(c);

%# fix the rows correspondingly
uniqueRows = r(sortIdx);

%# convert to index
idx = sub2ind(size(M),uniqueRows,uniqueCols);

%# get the numbers per column (transpose as needed)
numbers = M(idx)

numbers =

   -0.6000
    1.8000
   -2.3000
    3.4000
   -3.8000
   -4.3000
于 2010-04-15T13:26:50.453 回答
1

这是一个使用函数SUM的单行代码:

nonZeroColumnValues = sum(M)./sum(M ~= 0);

这将返回一个 1×n 向量,其中包含每列中重复的非零值。它通过对每一列求和,然后将结果除以每列中非零值的数量来实现。如果列中没有非零值,则该列的结果将为NaN

这是使用问题中的示例矩阵的示例M

>> M = [-0.6 1.8 -2.3 0 0 0; 0 0 0 3.4 -3.8 -4.3; -0.6 0 0 3.4 0 0]

M =

   -0.6000    1.8000   -2.3000         0         0         0
         0         0         0    3.4000   -3.8000   -4.3000
   -0.6000         0         0    3.4000         0         0

>> nonZeroColumnValues = sum(M)./sum(M ~= 0)

nonZeroColumnValues =

   -0.6000    1.8000   -2.3000    3.4000   -3.8000   -4.3000
于 2010-04-15T15:26:04.487 回答
0

M = M(M~=0)

或者

M(find(M))

请了解如何为 SO 读者格式化代码。

编辑 @Jonas 建议 OP 只希望 M 中的每个非零元素出现一次。要做到这一点,请尝试将上述建议中的任何一个包装在 中unique(),例如

unique(M(M~=0))
于 2010-04-15T12:33:48.860 回答
0

这实际上不是一个稀疏矩阵。MATLAB 中的稀疏矩阵就是这样定义的。如果您使用 sparse 或 spdiags 函数来定义该矩阵,则不需要存储零元素,只需要存储非零元素。当然,MATLAB 知道如何将这些真正的稀疏矩阵与其他标准双精度数组一起使用。

最后,真正的稀疏矩阵通常比这稀疏得多,否则您根本不会费心使用稀疏存储形式。

无论如何,如果您只想要 ANY 矩阵的非零元素,那么您可以这样做:

NZ = M(M ~= 0);

或者,

NZ = M(find(M));

要么按列将非零值串出,因为这就是数字在 MATLAB 中存储在矩阵中的方式。

NZ = M(find(M))
NZ =
         -0.6
         -0.6
          1.8
         -2.3
          3.4
          3.4
         -3.8
         -4.3

在您的问题中,您询问了如何按行执行此操作,提取第一行中的非零元素,然后是第二行等。

这最简单的方法是先转置数组。因此,我们可能会做类似...

NZ = M.';
NZ = NZ(find(NZ))
NZ =
         -0.6
          1.8
         -2.3
          3.4
         -3.8
         -4.3
         -0.6
          3.4

看我用过。进行转置,以防万一任何元素都很复杂。

于 2010-04-15T13:24:03.353 回答
0

如果 OP 真的想找到也是唯一的非零元素,那么有比 Jonas 建议的更好的方法来做到这一点。

逻辑解决方案是首先找到非零元素。然后应用唯一的功能。所以这样做:

unique(M(find(M)))

如果您的目标是以特定顺序查找这些元素,则需要在您的目标中明确定义该顺序。

于 2010-04-15T14:36:02.790 回答