Count number of values within a range in matrix per column and assign count to new matrix
30 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Juan Estrella-Martínez
am 6 Jun. 2020
Bearbeitet: dpb
am 7 Jun. 2020
Hi everyone. I'm using R2017b to work with a large matrix. The matrix is the result of calculating the value of an equation while looping through coefficients (and interpolating between coefficients) representing the 95% CI.
What I would like to do is:
1. Count the number of elements that fall under certain range on a per column basis (say, elements between 0 and 0.5)
2. Assign that count to an element of a different matrix
3. Repeat steps 1 and 2 using a new range (say, elements between 0.5 and 1.0)
4. Repeat steps 1 through 3 for all columns
Example:
Count values between 0 and 0.5, and 0.5 and 1.0 in matrix A and assign the results to matrix B
A= [
0.83 0.02
NaN 0.69
0.7 0.72
0.3 0.32
NaN 0.8
0.02 0.04
0.56 NaN
0.78 NaN
0.01 0.03
0.67 NaN];
B =
3 4 %% Number of elements that satisfy the first condition
5 3 %% Number of elements that satisfy the second condition
I think my question is related to this one: https://uk.mathworks.com/matlabcentral/answers/37196-count-number-of-specific-values-in-matrix.
Hope you can help. Cheers!
0 Kommentare
Akzeptierte Antwort
Image Analyst
am 7 Jun. 2020
This will do it:
A= [
0.83 0.02
NaN 0.69
0.7 0.72
0.3 0.32
NaN 0.8
0.02 0.04
0.56 NaN
0.78 NaN
0.01 0.03
0.67 NaN]
[ra, ca] = size(A)
ranges = [0, 0.5;
0.5, 1]
[rr, cr] = size(ranges);
B = zeros(rr, ca)
for row = 1 : rr
B(row, :) = sum(A > ranges(row, 1) & A <= ranges(row, 2), 1)
end
Just a simple for loop that should be easy to understand.
A > ranges(row, 1) & A <= ranges(row, 2) is a binary matrix that says how many elements are in that particular range. 1 if it's in the range and 0 if it's not in the range.
Then sum() just sums them up in each of the columns and the two column sums are assigned to a row in B.
Weitere Antworten (1)
dpb
am 6 Jun. 2020
>> reshape(cell2mat(arrayfun(@(c) histcounts(A(:,c),[0 0.5 1]),1:size(A,2),'UniformOutput',false)),[],size(A,2))
ans =
3.00 4.00
5.00 3.00
>>
Above assumes you can live w/ bins being non-inclusive right edge; ie
0 <= x1 < 0.5
0.5 <= x2 <= 1
as the last bin always includes right edge (which is different and often unwanted behavior relative to the deprecated histc())
Why TMW chooses to vectorize some things and not others is still a deep, dark mystery -- all the histXXX functions treat input arrays as one-column vectors--why is anybody's guess. One can always pass a vector if that's what's wanted; why the functions don't behave in a normal MATLAB pattern with most others is just baffling and another irritant. Hence the arrayfun to have to deal with each column.
2 Kommentare
dpb
am 7 Jun. 2020
Bearbeitet: dpb
am 7 Jun. 2020
Fundamentally same as IA's excepting uses histcounts and your bin edges instead of specific logic tests and arrayfun to do the for...end loop. The rest is just turning a cell array into a numeric array and rearranging in the desired order.
The advantage is (and I presumed would be need likely) this only takes changing the edges argument to histcounts and it will work for any number of bins; the other way you have to recode and add more logic tests if that should change.
The for loop version would be:
B=zeros(2,size(A,2)); % preallocate result array
for i=1:size(A,2) % loop over columns A
B(:,i)=histcounts(A(:,i),[0 0.5 1]).'; % calculate bin counts for each column
end
>> B
B =
3 4
5 3
>>
It's probably a better solution than trying to cram all together into one line...still will only require changing the edges vector to accomodate any change in bins.
My beef above is that a fundamental design precept of MATLAB is and most MATLAB functions operate by column on input 2D arrays -- excepting for some reason TMW didn't write any of the histogram-related functions that way but just arbitrarily treats the input array as a 1D vector. Makes no sense at all to have done so; one can always call the function using the (:) on the input array if one wants it treated in that fashion, or,if that's not elegant-enough, incorporate the 'all' optional parameter as has now been done for min/max to treat them globally instead of by column.
Siehe auch
Kategorien
Mehr zu Matrices and Arrays finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!