Here is a simple double array:
array=[3 1 1]
Largest element index is 1
or:
array=[3 9 1]
Largest element index is 2
How can I get the largest element index?
Use the second output argument of the max function:
[ max_value, max_index ] = max( [ 3 9 1 ] )
My standard solution is to do
index = find(array == max(array), 1);
which returns the index of the first element that is equal to the maximum value. You can fiddle with the options of find if you want the last element instead, etc.
If you need to get the max value of each row you can use:
array = [1, 2, 3; 6, 2, 1; 4, 1, 5];
[max_value max_index] = max(array, [], 2)
%3, 3
%6, 1
%5, 3
In Octave If
A =
1 3 2
6 5 4
7 9 8
1) For Each Column Max value and corresponding index of them can be found by
>> [max_values,indices] =max(A,[],1)
max_values =
7 9 8
indices =
3 3 3
2) For Each Row Max value and corresponding index of them can be found by
>> [max_values,indices] =max(A,[],2)
max_values =
3
6
9
indices =
2
1
2
Similarly For minimum value
>> [min_values,indices] =min(A,[],1)
min_values =
1 3 2
indices =
1 1 1
>> [min_values,indices] =min(A,[],2)
min_values =
1
4
7
indices =
1
3
1
Related
I want to compare every row of table with every other row of the same table to find row having lowest values.
F=table(a,b,c,d)
a=[1 2 1 3, 8 3 1 6]'
b=[3 2 1 3]'
c=[7 9 1 8]'
d=[4 6 1 6]'
How can I do it using for loop. Purposely third row is least valued row and it is the final answer. In big table, this is not known in advance.
Actually, I think your are mistakenly inverting columns and rows here. Anyway, let's make an example with both, using a matrix for the sake of simplicity.
Let's start with rows:
A = [
1 2 1 3;
8 3 1 6;
3 2 1 3;
7 9 1 8;
4 6 1 6
];
rows_sum = sum(A,2); % row-wise summation
[rows_sum_min,rows_sum_min_idx] = min(rows_sum);
The variable rows_sum_min will contain the minimum value (7 in this case) while the variable rows_sum_min_idx will contain the row indices that correspond to the minimum value (1 in this case, the first row).
And now the columns:
A = [
1 2 1 3;
8 3 1 6;
3 2 1 3;
7 9 1 8;
4 6 1 6
];
cols_sum = sum(A,1); % column-wise summation
[cols_sum_min,cols_sum_min_idx] = min(cols_sum);
The variable cols_sum_min will contain the minimum value (3 in this case) while the variable cols_sum_min_idx will contain the row indices that correspond to the minimum value (3 in this case, the third column).
I don't know why you want to to it with a for loop, since the main objective when coding with Matlab is trying to vectorize calculations as much as possible in order to obtain a superior performance. Anyway, if you really want a for loop... here is the example with columns:
A = [
1 2 1 3;
8 3 1 6;
3 2 1 3;
7 9 1 8;
4 6 1 6
];
[n,m] = size(A);
cols_sum = zeros(1,m);
for i = 1:n
cols_sum = cols_sum + A(i,:);
end
[cols_sum_min,cols_sum_min_idx] = min(cols_sum);
The result will be the same, you just consumed more time and cycles.
I have a matrix with a shape like below. I want to delete rows with duplicate values in the first column and leaving row with the smallest number of duplicate values in the second column. my matrix
`d =
1 1
2 1
4 1
8 2
2 2
5 4
2 4
6 4
7 3
`
I want to remove duplicate number 2 in the first column and leaving the row with the smallest number of duplicate values in the second row
result required:
1 1
4 1
8 2
2 2
5 4
6 4
7 3
Thanks for the helps. best regard.
We can sort the array regards to first column and replace elements of second column by their descending count
to obtain this array:
1 3
2 3
2 3
2 2
4 3
5 3
6 3
7 1
8 2
Then if we apply unique to this array indices of desirable rows can be obtained and then then those rows can be extracted:
1 1
2 2
4 1
5 4
6 4
7 3
8 2
If oreder of original data should be preserved more step required that commented in the code.
a=[...
1 1
2 1
4 1
8 2
2 2
5 4
2 4
6 4
7 3];
%steps to replace counts of each element of column2 with it
[a2_sorted, i_a2_sorted] = sort(a(:,2));
[a2_sorted_unique, i_a2_sorted_unique] = unique(a2_sorted);
h = hist(a2_sorted, a2_sorted_unique);
%count = repelems(h, [1:numel(h); h]);%octave
count = repelem(h, h);
[~,a2_back_idx] = sort(i_a2_sorted);
count = count (a2_back_idx);
b = [a(:,1) , count.'];
%counts shoule be sorted in descending order
%because the unique function extracts last element from each category
[b_sorted i_b_sorted] =sortrows(b,[1 -2]);
[~, i_b1_sorted_unique] = unique(b_sorted(:,1));
c = [b_sorted(:,1) , a(i_b_sorted,2)];
out = c(i_b1_sorted_unique,:)
%more steps to recover the original order
[~,b_back_idx] = sort(i_b_sorted);
idx_logic = false(1,size(a,1));
idx_logic(i_b1_sorted_unique) = true;
idx_logic = idx_logic(b_back_idx);
out = c(b_back_idx(idx_logic),:)
Create a function that finds the minimal duplicate from the right column, given an index from the left column:
function Out = getMinDuplicate (Index, Data)
Candidates = Data(Data(:,1) == Index, :); Candidates = Candidates(:, 2);
Hist = histc (Data(:,2), [1 : max(Data(:,2))]);
[~,Out] = min (Hist(Candidates)); Out = Candidates(Out);
end
Call this function for all unique values in column 1:
>> [unique(d(:,1)), arrayfun(#(x) getMinDuplicate(x, d), unique(d(:,1)))]
ans =
1 1
2 2
4 1
5 4
6 4
7 3
8 2
(where d is your data array).
For example, I have a 4x6 matrix A:
A =
0 0 0 0 4 3
0 2 1 0 0 0
0 5 0 8 7 0
8 9 10 3 0 2
I want to find the lowest location within the rows of A where non-zero elements are found for each column. It should go like this:
column 1 => row 4
column 2 => row 2
column 3 => row 2
column 4 => row 3
column 5 => row 1
column 6 => row 1
And the result should look like the following vector:
Result = [4, 2, 2, 3, 1, 1]
Anyone has any idea how to obtain this?
One approach to solve for a generic case -
[valid,idx] = max(A~=0,[],1)
out = idx.*valid
Sample run -
A =
0 0 0 0 -4 3
0 2 1 0 0 0
0 5 0 8 7 0
0 9 10 3 1 2
out =
0 2 2 3 1 1
As seen from the sample run, for a case when there are all zeros (column-1), we get output of zero to indicate that there are no non-zeros in that column.
It also takes care of negative numbers (column-5).
This should do it:
A = [0, 0, 0, 0, 4, 3;
0, 2, 1, 0, 0, 0;
0, 5, 0, 8, 7, 0;
8, 9, 10, 3, 0, 2];
indices = repmat((1:size(A))', [1, size(A, 2)]);
indices(A == 0) = NaN;
min(indices, [], 1)
Here indices is:
indices =
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
We then set every element of indices to NaN wherever A is zero, which gives us:
indices =
NaN NaN NaN NaN 1 1
NaN 2 2 NaN NaN NaN
NaN 3 NaN 3 3 NaN
4 4 4 4 NaN 4
We then simply take the minimum of each column
I can think of one combination that uses ind2sub and unique with find, I'm sure there's a better way.
With your given A, assuming it's an array of integers:
[r, c] = ind2sub(size(A), find(A ~= 0));
[~, ia, ~] = unique(c);
result = r(ia)';
Returns:
result =
4 2 2 3 1 1
I did it this way because find returns the linear indices of the array it's searching. MATLAB arrays are stored column-major in memory, so it's as if each column is stacked on top of the other. ind2sub converts these linear indices back to their subscripts based on the size of the original array. Then I use unique to find the first instance of each column and return those row numbers only.
One possible solution, using sum and cumsum:
Result = sum(cumsum(A ~= 0) == 0) + 1;
I have a vector A = [ 1 1 1 2 3 3 3 2 2 1 1 1 1 3 3 3 ].
I want to find the positions of every element and store this in its own matrix.
To be more specific, I want to find the position of every elements for each set of elements, in a n by m matrix (where m would be the type of element, and n would be the number of elements found in vector A).
So, for example, assuming there are only values 1, 2, and 3 in vector A, the first column of my matrix would be for values that are 1, and would read off (1, 2, 3, 10, 11, 12, 13) and the second column, for values of 2, would read off (4, 8, 9) and the third column, for values of 3, would read off (5, 6, 7, 14, 15, 16).
This one liner works as expected:
B = accumarray(A', 1:length(A), [], #(x) {sort(x)})
B is a cell array where B{i} contains the sorted list of indices where i is located.
This could be one approach -
%// For each element create a pair: [R,C], where the first element R would
%// represent its index position in input array and C would be their uniqueness
[R,C] = find(bsxfun(#eq,A(:),unique(A(:).'))) %//'
%// Find lengths of each unique group
lens = diff([0 ; find(diff(C)) ; numel(C)])
%// Store each element into groups based on the uniqueness and whose
%// values would be the index positions i.e. taken from R
out = mat2cell(R(:).',1,lens)
Sample run for given input -
>> A
A =
1 1 1 2 3 3 3 2 2 ...
1 1 1 1 3 3 3
>> celldisp(out)
out{1} =
1 2 3 10 11 12 13
out{2} =
4 8 9
out{3} =
5 6 7 14 15 16
Similar to Divakar's answer but with sort
[out,i] = sort(A);
out1 = diff(find([1,diff(out)]));
out2 = [out1,numel(A)-sum(out1(:))];
out3 = mat2cell(i,1,out2);
Results:
A = [ 1 1 1 2 3 3 3 2 2 1 1 1 1 3 3 3 ]; %// input
>> celldisp(out3)
out3{1} =
1 2 3 10 11 12 13
out3{2} =
4 8 9
out3{3} =
5 6 7 14 15 16
I'm trying to achieve row indexing of a matrix using an array of indices in Eigen-3.2.0 whose Matlab equivalent is the following: consider a matrix A:
>> A = [2 3 0 ; 1 9 2 ; 4 7 2]
A =
2 3 0
1 9 2
4 7 2
>> A( [1 3 2 1 3], : )
ans =
2 3 0
4 7 2
1 9 2
2 3 0
4 7 2
I've been able to obtain an array of row indices ( of the type MatrixXd::Index ) which contains the numbers (1, 3, 2, 1, 3). But I've not been able to figure out a way of applying this array to the Matlab-like indexing described above. Is this even possible in Eigen? Or is there a smarter way of doing it? Any help at all will be great.
Thanks!