我有一个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]
在此示例中,第一列包含0
和-0.6
,第二列0
和1.8
,第三列-2.3
等等。
在这种情况下,我想将m减少到1(从给定矩阵中获取一个向量),所以在这个例子中,向量将是[-0.6 1.8 -2.3 3.4 -3.8 -4.3]
有谁知道从这样的矩阵中获取矢量的最佳方法是什么?
谢谢!
答案 0 :(得分: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
答案 1 :(得分:1)
这是一个使用函数SUM的单行程序:
nonZeroColumnValues = sum(M)./sum(M ~= 0);
这将返回1-by-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
答案 2 :(得分:0)
M = M(M~=0)
或
M(find(M))
请学习如何格式化SO读者的代码。
EDIT @Jonas建议OP只希望M中的每个非零元素出现一次。要尝试在unique()
中包含上述任何一个建议,例如
unique(M(M~=0))
答案 3 :(得分:0)
这实际上不是稀疏矩阵。 MATLAB中的稀疏矩阵就是这样定义的。如果使用sparse或spdiags函数来定义该矩阵,则不需要存储零元素,只需要存储非零元素。当然,MATLAB知道如何与其他标准双数组一起使用这些真正的稀疏矩阵。
最后,真正的稀疏矩阵通常比这稀疏得多,或者你根本不打算使用稀疏存储形式。
无论如何,如果您只想要任何矩阵的非零元素,那么您可以这样做:
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
看到我用过的。进行转置,以防任何元素都很复杂。
答案 4 :(得分:0)
如果OP真的想要找到同样独特的非零元素,那么有更好的方法可以做到这一点,而不是Jonas建议的。
逻辑解决方案是首先找到非零元素。然后应用唯一的功能。所以这样做:
unique(M(find(M)))
如果您的目标是按特定顺序查找这些元素,则需要在目标中明确定义该顺序。