Faster way for find some value in matrix with matlab - arrays

I have a matrix and I am trying to find where i getting a value. so, i am using find(x==y)for making vectors with the values, for example:
n11=find(x==11)
n4=find(x==4)
n8=find(x==8)
And n11, n4, n8 are not of the same length.
Sometimes, i have to do this like 20 or 30 times for 20 or 30 different values of x, so if for example i want to get an interval of x∈[1991,2015] find(x==1991) to find(x==2015) how can i get those values faster without doing
find(x==1991)
.
.
.
find(x==2015)
thank you

You can use logical indexing:
n= find(x>=1991 & x<=2015)
EDIT
meshgrid can be used to obtain a vector for each year:
x= [1991 1992 1991 2015 2016 1992 1988 1994]; % example data
[m,n]= meshgrid(x,1991:2015); % the second argument contains the years we need
n= (m==n);
Now n(1,:) is equal to x==1991, n(2,:) is equal to x==1992 etc; find(n(1,:)) equals find(x==1991) etc.

you can use a matrix for saved results. and use "for loop" for doing automaticly.
start=1991;
endi=2015;
for i=start:endi
num_column=size(find(x==i),1)
mat(i-start+1,1:num_column)=find(x==i);
end
In each row, we have result of one value ignoring zero numbers.

Related

How to ignore a ROW in Average function, set up by a Max function?

I will try my best to explain my dilemma; in Column B23:B37 is a list of numbers from which I would like to get the Average (Function - =AVERAGE(B23:B37)).
The problem is, the biggest number (B30 = 8.3) should not be counted in the Average function.
My solution to this, is =ARRAYFORMULA(AVERAGE(IF(B23:B37<>MAX(B23:B37);B23:B37)))
And the result you can see in the image = 1.73
The thing is, as you can see in de Column A (same list of number, just without the 8.3 number) equals 2.22 . I guess, that the real average, without the B30 Row.
My formula must be all wrong! how can I make this work?

How to generate a payroll condition using array formula

I want to make a condition that if the day is more than or equal 16 and less than or equal 31 the formula returns the same month adding to it the word payroll and if the day is from 1 to 14 formula returns previous month adding to it the word payroll
The equation is working but without the array formula and I need it in array to auto drag
Here is the equation without the array formula:
=IF(A2="","",if(AND(B2>=16,B2<=31),TEXT(DATE(2019,C2,1),"MMM"),TEXT(DATE(2019,C2-1,1),"MMM"))&" Payroll")`
Here is the equation in the array formula:
=ARRAYFORMULA(IF(ROW(A:A)=1,"Payroll Array",IF(A:A="","",if(AND(B:B>=16,B:B<=31),TEXT(DATE(2019,C:C,1),"MMM"),TEXT(DATE(2019,C:C-1,1),"MMM"))&" Payroll")))
here is a sample datasheet to see the difference as the array formula doesn't return the correct value I need: Link
also possible to do it as standalone like:
={"Payroll Array"; ARRAYFORMULA(IF(A2:A="",,
IF((DAY(A2:A)>=16)*(DAY(A2:A)<=31), TEXT(A2:A, "MMM"),
TEXT(EOMONTH(A2:A, -1), "MMM"))&" Payroll"))}
try:
=ARRAYFORMULA(IF(ROW(A:A)=1,"Payroll Array",
IF(A:A="",,IF((B:B>=16)*(B:B<=31), TEXT(DATE(2019, C:C, 1), "MMM"),
TEXT(DATE(2019, C:C-1, 1), "MMM"))&" Payroll")))
check this out, it should work:
=Arrayformula(if(B2:B>=16,if(B2:B<=31,TEXT(DATE(2019,C2:C,1),"MMM"),TEXT(DATE(2019,C2:C-1,1),"MMM")),TEXT(DATE(2019,C2:C-1,1),"MMM"))&" Payroll")

Using an Array to get the average of a selection of numbers

I have 12 different numbers on a row in an excel sheet (repeated few times on different row) and I would like to get the average of the 8 bigger numbers (4 numbers won't be used). I thought to use an array, but how to select the 8 bigger numbers in this array?
I would like to do it in VBA. Do you have any ideas/directions how to proceed, because I am not really sure how to start.
Example: 12,3,5,6,8,11,9,7,5,8,10,1 (Results=8.875), if I didn't make a mistake!
Thanks.
I know you asked for VBA, but here's a formula. If this works, you can quickly throw in VBA (use the macro recorder to see how if you're unsure).
If that's in row 1, you can use:
=AVERAGE(LARGE(A1:L1,{1,2,3,4,5,6,7,8}))
You should be able to change A1:l1 to be the range where your numbers are, i.e.
=AVERAGE(LARGE(A1:F2,{1,2,3,4,5,6,7,8}))
Edit: Per your comment, also no need for VBA. Just use conditional highlighting. Highlight your range of numbers, then go to Conditional Highlighting --> Top/Bottom Rules --> Top 10 Items. Then just change the 10 to 8, and choose a color/format. Then Apply!
(each row in the above is treated as it's own range).
Edt2: bah, my image has duplicate numbers which is why the top 8 rule is highlighting 9 numbers sometimes. If you request I'll try to edit and tweak
You can use a simple Excel function to compute the answer
=AVERAGE(LARGE(A1:L1, {1,2,3,4,5,6,7,8}))
It is a bit more complex in VBA, but here is a function that does the same computation (explicit typing per Mat's Mug):
Public Function AvgTop8(r As Range) As Double
Dim Sum As Double, j1 As Integer
For j1 = 1 To 12
If WorksheetFunction.Rank(r(1, j1), r) <= 8 Then
Sum = Sum + r(1, j1)
End If
Next j1
AvgTop8 = Sum / 8#
End Function
The Excel RANK function returns the rank of a number in a list of numbers, with the largest rank 1 and so on. So you can search through the 12 numbers for the 8 largest, sum them and divide by 8.
You don't need VBA for this. You can use:
=AVERAGE(LARGE(A1:L1,{1;2;3;4;5;6;7;8}))

Replace several numbers in an array every step in Matlab

I am having a set of data. Let's say a grid-points nxm (n latitude, m:longitude) daily temperature for the whole world during a month. However, the temperature in my location of interest is not correct, so I need to update it. In other words, I have to change the data at some certain grid points for every time step (daily). I attach here a simple example. Let's say each matrix 1x2 on the left is the correct data, while each 6x4 matrix contains some incorrect data (6: latitude, 4: longitude). What I need is to change the correct data from the left to the right as indicated in the same color for every time step.
Could anyone help me?
Many thanks
For example this data:
A=rand(4,2)
B=rand(6,4,4)
You would want these values to be replaced by A:
B(3,2:3,:)
Just make sure the size is the same
size(B(3,2:3,:))
> 1 2 4
A=reshape(A',[1 2 4])
And you can put it there
B(3,2:3,:)=A
[edit] Sorry, I probably just don't see the problem.
T = randi(255,[1E3,1E3,31],'uint8'); %1000 longitude, 1000 latitude, 31 days
C = repmat([50,100],[31,1,1]); %correction for 31 days and two locations. must become 50 and 100.
%location 20,10 and 20,11 must change.
T(20,10:11,:)=reshape(C',[1 2 31]);
T(20,10,3) %test for third day.
>> 50
T(20,11,10) %test for tenth day.
>> 100
The replacement takes 0.000365 second on my pc.

Excel complicated array

I have a very long formula that churns out the correct answer when it is just focussed on calculating one row.
I want to turn this into an array that will sum over multiple rows, however as soon as i turn the formula into an array it then gives an incorrect value... and i don't know why! For some reason it seems to do an extra multiplication when i put it into an array, i believe anyway.
Original working formula on single row:
=(IFERROR(.........
+12.5*$C15), ....)
Not working array:
{=SUM(IFERROR(.........
+12.5*$C15:$C16), ....)
When C15 is 0.5, the array returns a value that is 6.25 too low
When C15 is 1, the array returns a value that is 12.5 too low
When C15 is 1, the array returns a value that is 25 too low
So it is most definitely something to do with the 12.5 but i don't understand why turning it into an array makes it return a value too low.
Based on the duplicate question found here: https://stackoverflow.com/questions/42025870/excel-array-formula-complicated?noredirect=1
You do not need the IFERROR:
The CSE array formula:
=SUM(IF(ISNUMBER(SEARCH("S",B2:B3,1), 1, 2))
Remove the quotes around the numbers, with quotes they are strings and SUM will ignore them.
The ISNUMBER takes the place of the IFERROR.
This is an array formula and needs to be confirmed with Ctrl+Shift+Enter.
If done correctly then Excel will put {} around the formula.

Resources