How to locate an entire column based on one value?
8 views (last 30 days)
Show older comments
I have a 25x420 matrix. I want to locate the median number within the matrix. Once the median is located, I want to call the column that it came out of. If i do "median(t)" it gives the median of each column but from there I can call the total median value and its column of values.
columns = 25;
rows = 420;
t = rand(rows,columns);
0 Comments
Answers (1)
Star Strider
on 30 Aug 2024
Edited: Star Strider
on 30 Aug 2024
The way the median is calculated may not exactly match any of the values in the matrix.
The solutiion to that problem is to use the ismembertol function to find the element or elements that are the closest match to it. That returns a logical array, and using find with that result will return the rows and columns of the closest matches that ismembertol returns.
Try something like this —
columns = 25;
rows = 420;
t = rand(rows,columns);
tmed = median(t, 'all')
[r,c] = find(ismembertol(t, tmed, 1E-4));
row_col = [r c]
idx = sub2ind(size(t), r, c)
t(idx)
.
EDIT — Corrected typographical errors.
5 Comments
Star Strider
on 3 Sep 2024
My pleasure!
I limited this to a small matrix for ease of interpretation and readability. Everything here would also apply to your (25x420) matrix.
Just using median will return the column medians of a matrix —
A = randn(10)
ColMed = median(A)
Check1 = median(A,'all') == median(ColMed) % Is The Matrix Median Equal To The Medain Of The Column Medians?
Look = [median(A,'all') median(ColMed)] % Show Their Individual Values
Check2 = ColMed == median(ColMed) % Is The Median Of The Column Medians Equal To Any Of Them?
[r,c] = find(ismembertol(A, Look(1), 1E-2));
row_col = [r c]
idx = sub2ind(size(A), r, c)
A(idx)
However, the median of the entire array may not equal the median of the column medians, and the median of the column medians may not be equal to any of them.
Your matrix has an even number of elements (10500), so it is not likely that any one of them will equal the median of the matrix.
It may not be possible to do what you describe wanting to do. (I am not even certain what that is.)
.
Walter Roberson
on 3 Sep 2024
Since the input is 25 x 420 and the desired output is 1 x 420 then the per-column median is desired. That is an odd number of entries in the columns, so (provided that there are no nan values) the per-column median will be exactly the same as (at least one of) the rows.
A = rand(25,9);
Medians = median(A);
tic
Per_row_position = sum(cumprod(Medians ~= A)) + 1;
toc
A
Medians
Per_row_position
The sum(cumprod) is a trick to locate the positions of matching entries in a parallel manner. It is effectively a
tic
Per_row_position2 = arrayfun(@(IDX) find(A(:,IDX)==Medians(IDX),1), 1:size(A,2))
toc
... except that it takes more memory, and is a bit faster.
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!