How to locate an entire column based on one value?

8 vues (au cours des 30 derniers jours)
Kendell
Kendell le 30 Août 2024
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);

Réponses (1)

Star Strider
Star Strider le 30 Août 2024
Modifié(e) : Star Strider le 30 Août 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')
tmed = 0.5053
[r,c] = find(ismembertol(t, tmed, 1E-4));
row_col = [r c]
row_col = 2x2
111 3 320 19
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
idx = sub2ind(size(t), r, c)
idx = 2x1
951 7880
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
t(idx)
ans = 2x1
0.5053 0.5052
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
.
EDIT — Corrected typographical errors.
  5 commentaires
Star Strider
Star Strider le 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)
A = 10x10
-0.1840 1.0885 -2.0206 -1.1134 -0.8050 -1.0294 0.2714 1.1347 -0.0150 -0.4304 -0.4164 -0.2513 -0.9963 0.0027 -1.9010 -0.2864 -0.8389 -1.1578 -0.4903 -0.4042 0.0074 -0.7934 0.1429 -0.9668 -1.1607 -0.9066 0.3446 -1.1123 0.2136 1.1778 -0.3832 2.2025 -1.4934 0.3030 -0.3217 -0.1841 -0.3007 -1.4484 -0.3797 0.7890 0.0230 1.9308 -0.9886 0.4529 0.5115 0.8189 0.2398 0.5702 1.3789 -0.3604 0.4196 -0.6768 0.7539 -1.2780 -0.2931 0.4088 -1.7036 -0.3930 -2.7188 -0.7861 -0.0164 -0.2707 -1.3897 -0.6175 -0.7291 0.5047 1.1061 1.8219 1.0016 0.5403 -0.7049 0.1320 -1.3270 -0.4939 0.6516 0.1642 -1.3163 -1.7062 -0.0860 -1.2845 0.4395 1.5823 0.1089 -0.9712 0.1382 -0.4037 1.0458 0.3306 -3.4837 0.0383 -0.4066 1.8031 0.5805 -0.1327 -1.8988 0.7264 1.1519 0.0072 -1.3220 0.2506
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
ColMed = median(A)
ColMed = 1x10
-0.1002 0.6102 -0.9924 -0.5557 -0.5254 -0.0100 0.2556 -0.1929 -0.2328 -0.1610
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Check1 = median(A,'all') == median(ColMed) % Is The Matrix Median Equal To The Medain Of The Column Medians?
Check1 = logical
0
Look = [median(A,'all') median(ColMed)] % Show Their Individual Values
Look = 1x2
-0.2177 -0.1770
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Check2 = ColMed == median(ColMed) % Is The Median Of The Column Medians Equal To Any Of Them?
Check2 = 1x10 logical array
0 0 0 0 0 0 0 0 0 0
[r,c] = find(ismembertol(A, Look(1), 1E-2));
row_col = [r c]
row_col = 3x2
1 1 2 2 4 6
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
idx = sub2ind(size(A), r, c)
idx = 3x1
1 12 54
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
A(idx)
ans = 3x1
-0.1840 -0.2513 -0.1841
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
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
Walter Roberson le 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
Elapsed time is 0.009425 seconds.
A
A = 25x9
0.2929 0.0002 0.6991 0.6386 0.9287 0.4889 0.4289 0.5787 0.8547 0.3655 0.1354 0.6275 0.6950 0.6883 0.8430 0.3727 0.2921 0.6618 0.3457 0.0778 0.2939 0.4399 0.9086 0.4457 0.5634 0.0411 0.9461 0.4961 0.5700 0.9381 0.4805 0.9934 0.0828 0.7613 0.9223 0.0802 0.7434 0.8918 0.5773 0.0723 0.2984 0.9813 0.1776 0.1028 0.5910 0.8836 0.6333 0.4246 0.3437 0.6069 0.6538 0.7859 0.5676 0.6423 0.0592 0.1362 0.6600 0.2060 0.0555 0.3239 0.7298 0.0782 0.3453 0.7516 0.6257 0.8540 0.9461 0.9035 0.2747 0.4924 0.0449 0.1229 0.4251 0.2896 0.8255 0.2323 0.1255 0.6340 0.8271 0.0264 0.2677 0.7647 0.2324 0.6675 0.0428 0.2056 0.0075 0.4890 0.6607 0.5377
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Medians
Medians = 1x9
0.4251 0.3908 0.4670 0.4922 0.6719 0.4889 0.5199 0.5676 0.3242
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Per_row_position
Per_row_position = 1x9
9 25 21 18 22 1 18 6 11
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
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))
Per_row_position2 = 1x9
9 25 21 18 22 1 18 6 11
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
toc
Elapsed time is 0.015615 seconds.
... except that it takes more memory, and is a bit faster.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Produits


Version

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by