问题
I have a matrix of 2d lets assume the values of the matrix
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
17 24 1 8 15
11 18 25 2 9
This matrix is going to be divided into three different matrices randomly let say
b =
17 24 1 8 15
23 5 7 14 16
c =
4 6 13 20 22
11 18 25 2 9
d =
10 12 19 21 3
17 24 1 8 15
How can i know the index of the vectors in matrix d for example in the original matrix a,note that the values of the matrix can be duplicated. for example if i want to know the index of {10 12 19 21 3} in matrix a? or the index of {17 24 1 8 15} in matrix a,but for this one should return only on index value? I would appreciate it so much if you can help me with this. Thank you in advance
回答1:
You can use ismember
with the 'rows'
option. For example:
tf = ismember(a, c, 'rows')
Should produce:
tf =
0
0
1
0
0
1
To get the indices of the rows, you can apply find
on the result of ismember
(note that it's redundant if you're planning to use this vector for matrix indexing). Here find(tf)
return the vector [3; 6]
.
If you want to know the number of the row in matrix a
that matches a single vector, you either use the method explained and apply find
, or use the second output parameter of ismember
. For example:
[tf, loc] = ismember(a, [10 12 19 21 3], 'rows')
returns loc = 4
for your example. Note that here a
is the second parameter, so that the output variable loc
would hold a meaningful result.
Handling floating-point numbers
If your data contains floating point numbers, The ismember
approach is going to fail because floating-point comparisons are inaccurate. Here's a shorter variant of Amro's solution:
x = reshape(c', size(c, 2), 1, []);
tf = any(all(abs(bsxfun(@minus, a', x)) < eps), 3)';
Essentially this is a one-liner, but I've split it into two commands for clarity:
x
is the target rows to be searched, concatenated along the third dimension.bsxfun
subtracts each row in turn from all rows ofa
, and the magnitude of the result is compared to some small threshold value (e.g eps). If all elements in a row fall below it, mark this row as "1".
回答2:
It depends on how you build those divided matrices. For example:
a = magic(5);
d = a([2 1 2 3],:);
then the matching rows are obviously: 2 1 2 3
EDIT:
Let me expand on the idea of using ismember
shown by @EitanT to handle floating-point comparisons:
tf = any(cell2mat(arrayfun(@(i) all(abs(bsxfun(@minus, a, d(i,:)))<1e-9,2), ...
1:size(d,1), 'UniformOutput',false)), 2)
not pretty but works :) This would be necessary for comparisons such as: 0.1*3 == 0.3
(basically it compares each row of d
against all rows of a
using an absolute difference)
来源:https://stackoverflow.com/questions/16716547/finding-index-of-vector-from-its-original-matrix