Remove rows containing duplicate elements - matlab

I have this example matrix:
1 2 4 5 1 3
2 3 5 6 3 4
1 2 3 4 5 6
3 2 4 6 1 5
...
I need to delete each row that contains duplicate elements. In this example I have to delete the first and second rows.
I know how to do this in a for-loop, but I don't want to use a for-loop.

Assuming A as the input matrix, you could do -
A(all(diff(sort(A,2),[],2),2),:)
Sample run -
>> A
A =
1 2 4 5 1 3
2 3 5 6 3 4
1 2 3 4 5 6
3 2 4 6 1 5
>> A(all(diff(sort(A,2),[],2),2),:)
ans =
1 2 3 4 5 6
3 2 4 6 1 5
Alternatively, if you don't mind some bsxFUN -
A(~any(sum(bsxfun(#eq,A,permute(A,[1 3 2])),2)>1,3),:)

Related

How to duplicate all inner columns of a matrix and sum pairs of columns in Matlab

Suppose I have a matrix A
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
How do I duplicate the inner columns of A to get a new matrix B
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
Notice the first and last column of A were left alone. Then I need to sum pairs of rows together to get another matrix C:
3 5 7 9
3 5 7 9
3 5 7 9
3 5 7 9
3 5 7 9
The size of my matrices will not always be 5x5 and the elements will not always be so nice, but the matrix will always be square.
I do not need to generate or output matrix B. That was just simply how I initially thought of obtaining my final matrix C.
My goal is to be reasonably efficient, so I would like to accomplish this without a for loop.
How do I accomplish this for arbitrary matrix size nxn ?
Very simple . .
C = A(:,2:end) + A(:,1:end-1)

how to delete empty elements in the cell in a way i want

in MATLAB I have a cell array like this
a = { 1 2 2 3 4 5 [] []
2 4 5 4 3 2 4 5
4 5 4 3 4 [] [] []}
I want to remove empty elements in a way that I get this :
a = { 1 2 2 3 4 5 2 4 5 4 3 2 4 5 4 5 4 3 4}
but when I use this : a(cellfun(#isempty,a)) = [];
what I get is this :
a = {1 2 4 2 4 5 2 5 4 3 4 3 4 3 4 5 2 4 5}
which is not what I want
The problem is that the linear index runs in the direction of rows, i.e. it runs through the first conlumn, then through the second column etc.
You can see this when you call reshape on a vector:
>> reshape([1 2 3 4 5 6 7 8 9],3,3)
ans =
1 4 7
2 5 8
3 6 9
To achieve the result you want, you need to transpose a before indexing into it.
a = a';
a(cellfun(#isempty,a)) = [];
You can try this :
A(~cellfun('isempty',A))

MatLab:Grouping non-zero values depending of values in another vector

Lets say,we've the following two vectors:
data = [1 2 2 2 3 3 3 3 3 3 4 4 4 4 4 ];
x_axis = [1 1 1 2 2 2 3 3 3 3 3 4 4 5 5 ];
What i now want to have is to count all data values which are for example one in the x_axis ,then these values which are two etc. So the result should look like as following (which i then can represent as a histogram):
result=[5 8 16 8 8];
x_axis=[1 2 3 4 5];
This is the perfect application example for accumarray:
data = [1 2 2 2 3 3 3 3 3 3 4 4 4 4 4 ];
x_axis = [1 1 1 2 2 2 3 3 3 3 3 4 4 5 5 ];
result = accumarray(x_axis(:),data(:),[],#sum)
result =
5
8
16
8
8

I want to group the columns of the matrix A which have the same value for the third line in Matlab

For a matrix A (4 rows, 1000 columns). I want to group the columns of the matrix A which have the same value for the third line. so I must have sub matrix with a third row that contains the same value.
for example:
if:
A =
1 4 5 2 2 2 2 1 1 5
1 4 5 4 4 2 2 4 5 2
3 3 3 3 4 1 3 5 3 4
4 5 5 5 4 1 5 5 5 5
then
A1 =
1 4 5 2 2 1
1 4 5 4 2 5
3 3 3 3 3 3
4 5 5 5 5 5
A2 =
2 5
4 2
4 4
4 5
A3 =
2
2
1
1
the result can be in the form of a cell.
here's one possible hack (warning: I haven't been able to check this):
A =
1 4 5 2 2 2 2 1 1 5
1 4 5 4 4 2 2 4 5 2
3 3 3 3 4 1 3 5 3 4
4 5 5 5 4 1 5 5 5 5
specialRow=3;
unqCols = unique(A(specialRow,:));
numUnq = length(unqCols);
sepMats{numUnq}=[];
for i=1:numUnq
sepMats{i} = A(:,A(specialRow,:)==unqCols(i));
end
In the example you shown, there are 4 unique elements in the 3rd row, so you should obtain 4 submatrices, but you only show 3 ?
Here is one way:
clear all;
%data
A = [1 4 5 2 2 2 2 1 1 5;
1 4 5 4 4 2 2 4 5 2;
3 3 3 3 4 1 3 5 3 4;
4 5 5 5 4 1 5 5 5 5
]
%engine
row = 3;
b = unique(A(row,:));
r = arrayfun(#(i) A(:,A(row,:)==b(i)),1:length(b), 'UniformOutput',false);
r{:}
You can make the assignment in a single line using ACCUMARRAY:
A = [1 4 5 2 2 2 2 1 1 5;
1 4 5 4 4 2 2 4 5 2;
3 3 3 3 4 1 3 5 3 4;
4 5 5 5 4 1 5 5 5 5
];
out = accumarray(A(3,:)', (1:size(A,2)), [], #(x){A(:,x)} );
With this, out{i} contains all columns of A where the third row of A equals i (and empty in case there is no valid column).
If you want out{i} to contain columns corresponding to the i-th smallest unique value in the third row of A, you can use GRP2IDX from the statistics toolbox first:
[idx,correspondingEntryInA] = grp2idx(A(3,:)'); %'#
out = accumarray(idx, (1:size(A,2)), [], #(x){A(:,x)} );
Here, out{i} contains the columns corresponding to correspondingEntryInA(i).

How to get all possible combinations of K items from a total of N in MATLAB

For e.g., if [1,2,3,4,5,6] is a vector, then all possible combinations of 3 items at a time is
4 5 6
3 5 6
3 4 6
3 4 5
2 5 6
2 4 6
2 4 5
2 3 6
2 3 5
2 3 4
1 5 6
1 4 6
1 4 5
1 3 6
1 3 5
1 3 4
1 2 6
1 2 5
1 2 4
1 2 3
How do I find this in MATLAB?
Try this link. Basically you just need to type c = combnk(1:6,3). Hope it helps.
Edit: The difference between what I proposed and #nash 's combntns is the toolbox that the commands are in. combnk is in the Statistics Toolbox, while combntns is in the Mapping Toolbox.
>> combos = combntns([1 2 3 4 5 6], 3)
Output:
1 2 3
1 2 4
1 2 5
1 2 6
1 3 4
1 3 5
1 3 6
1 4 5
1 4 6
1 5 6
2 3 4
2 3 5
2 3 6
2 4 5
2 4 6
2 5 6
3 4 5
3 4 6
3 5 6
4 5 6
I use:
allCombos = nchoosek([1:n],k);
I prefer this, as nchoosek comes with Matlab, no toolbox needed.