Replace negative values with zero and values above 1 with 1, using loop in a 8760 x 1000 matrix
조회 수: 11 (최근 30일)
이전 댓글 표시
Dear all,
I have a simple question that I can not solve.
I have a 8760 x 1000 matrix in which some values are negative, and some are larger than 1. The matrix represents 1000 simulation outcomes for 8760 hourly wind energy capacity factors in a year. I want to replace the negative values with zero, and the values that are larger than 1 with 1. Also I want to count how many values I have replaced in any given run.
So far I have been first counting values that are above 1 and below 0 for the entire matrix using the numel function. This gives me just one number for the entire matrix. However I would like to obtain the number of values below 0 and above 1 for all of the 1000 simulations. Then after I get this I want to run a loop for replacing these values with 0 (when beloe zero) and 1 (when above one).
So far this is the code I have been using:
%DATA CORRECTION
%count data we correct
CountIF_exc_1 = numel(SimWind_CapFac_UP(SimWind_CapFac_UP>1));
CountIF_neg = numel(SimWind_CapFac_UP(SimWind_CapFac_UP<0));
%correct data
SimWind_CapFac_UP_corrected = zeros(SimHours,numberSim);
for y = 1:numberSim
for x = 1:SimHours
if SimWind_CapFac_UP_corrected(x,y) > 1
SimWind_CapFac_UP_corrected(x,y) = 1;
elseif SimWind_CapFac_UP_corrected(x,y) < 0
SimWind_CapFac_UP_corrected(x,y) = 0;
end
end
end
This is however resulting in all zeros.
In summary could you please help me develop code to: a) count values that are below 0 and above 1 for each individual simulation run (the 1000 runs) and b) loop through the 8760 x 1000 matrix to replace these values with either 0 or 1.
Thanks a lot!
댓글 수: 0
채택된 답변
Chris
2021년 11월 2일
편집: Chris
2021년 11월 2일
Is there a reason you want to do it in a loop?
Matlab excels at vectorized operations. The following is simpler and faster than a loop:
negmask = SimWind_CapFac_UP(:)<0;
excmask = SimWind_CapFac_UP(:)>1;
CountIF_neg = sum(negmask);
CountIF_exc_1 = sum(excmask);
NEWMATRIX = SimWind_CapFac_UP;
NEWMATRIX(negmask) = 0;
NEWMATRIX(excmask) = 1;
댓글 수: 5
Chris
2021년 11월 4일
편집: Chris
2021년 11월 4일
For future reference, to sum across rows, sum() allows a second argument indicating the direction in which to sum: sum(negmask,2)
1) For a typical language you would need to use loops, but as matlab was designed for matrix math, it has many features that make working with matrices and vectors easier, and usually faster than a loop. For a matrix A, A < 0
returns a matrix of the same size as A, with all elements less than zero identified. I added the colon (:) to return a vector, because the intent was to sum over all elements. Another method (which I probably should have used here instead) would be:
A = randi([-1, 2], 4);
count_neg = A<0
sum(count_neg,'all')
This sums all elements of the matrix, rather than all rows or all columns.
A(count_neg) = 9
2) Arrays have a standard counting order--across each dimension, in order. Even with 3-dimensional or higher arrays, you could move through all elements one at a time without considering the dimensions. A 2D, mxn matrix is counted along columns (the first dimension), followed by rows.
vec = 1:9
reshape(vec,3,3)
As long as a vector has an equal number of elements as the array to which it is being compared, Matlab will iterate through the matrix in that order, comparing (or operating on) the nth element of vector x with the nth element of matrix A.
Does that help a little?
Also, for counting by columns, I think Stephen's answer does what you want in an even more condensed fashion.
참고 항목
카테고리
Help Center 및 File Exchange에서 Logical에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!