Reputation: 2411
I have 3D matrix like this
1 5648.00278672228 -46.43159546036
1 5650.38906894239 68.81787768047
1 5649.13081105839 -4867.55961979647
1 5650.53055771227 4868.95936645035
1 5647.95215053492 4866.38095927300
1 5650.21656586142 -2328.64537459950
1 5651.76371933598 7870.19252807406
1 5649.87288540620 -1168.30169414428
and I want to extract positive and negative values of 3rd column into two seperate 2D matrices (POS and NEG) where 1st column contains the index of the row from the above matrix, and second column contains the value.
The result should look like
POS =
2 68.81787768047
4 4868.95936645035
5 4866.38095927300
7 7870.19252807406
and
NEG =
1 -46.43159546036
3 -4867.55961979647
6 -2328.64537459950
8 -1168.30169414428
Upvotes: 2
Views: 6290
Reputation: 38052
Here is yet another way:
B = [(1:size(A,1)).' A(:,3)];
inds = B(:,2)>0;
POS = B( inds,:);
NEG = B(~inds,:);
This is faster than Magla's find
solution:
tic
for ii = 1:1e5
B = [(1:size(A,1)).' A(:,3)];
inds = B(:,2)>0;
POS = B( inds,:);
NEG = B(~inds,:);
end
toc
tic
for ii = 1:1e5
POS = [find(A(:,3)>0) A(A(:,3)>0,3)];
NEG = [find(A(:,3)<=0) A(A(:,3)<=0,3)];
end
toc
Results on my crappy machine:
Elapsed time is 1.290744 seconds. % my new solution
Elapsed time is 2.004015 seconds. % Magla's solution w/ find()
This difference is partly due to skipping find
, negating the logical indices instead of comparing again to <= 0
, and re-using the indices instead of re-computing them.
Even compared to a more optimal version of Magla's solution:
tic
for ii = 1:1e5
inds = A(:,3)>0;
POS = [find( inds) A( inds,3)];
NEG = [find(~inds) A(~inds,3)];
end
toc
we find
Elapsed time is 1.290744 seconds. % my new solution
Elapsed time is 1.476138 seconds. % Magla's solution w/ find()
Upvotes: 3
Reputation: 7751
You may use the find
function and logical indexing
POS = [find(A(:,3)>0) A(A(:,3)>0,3)]
NEG = [find(A(:,3)<=0) A(A(:,3)<=0,3)]
For your input matrix being A
A = [1 5648.00278672228 -46.43159546036
1 5650.38906894239 68.81787768047
1 5649.13081105839 -4867.55961979647
1 5650.53055771227 4868.95936645035
1 5647.95215053492 4866.38095927300
1 5650.21656586142 -2328.64537459950
1 5651.76371933598 7870.19252807406
1 5649.87288540620 -1168.30169414428]
the results will be (with format shortG
)
POS =
2 68.818
4 4869
5 4866.4
7 7870.2
NEG =
1 -46.432
3 -4867.6
6 -2328.6
8 -1168.3
the second find was removed thanks to @Dennis Jaheruddin and Khurram Majeed' comments.
Upvotes: 3
Reputation: 21561
Here is an alternate way to do it
p = find(A(:,3)>0);
n = find(A(:,3)<0);
POS = [p A(p,3)]
NEG = [n A(n,3)]
Note that this does not include zero entries. If you want them in the first vector for example use >=
instead of >
.
Upvotes: 3