The following code aims to average 4 groups of the values
vector. Which elements belong to each group is determined by the indic
vector and two split variables x1, x2
:
- Group 1: those elements where
indic
is between 0 and x1, - Group 2: those elements where
indic
is between x1 and x2,
and so on. The correspondence between the values
vector and the indic
is by position in the vector.
As a result, the code returns a list of the same length as values with the corresponding averages.
(* Input variables *)
indic = RandomChoice[Range[1,100], 1000];
values= RandomReal[{0,10}, 1000];
(* given certain breaks on indic, I want to calculate average on the values *)
myfun[x1_, x2_]:= Module[{avgVal, breaks, setAvg},
avgVal=ConstantArray[Missing, Length[values]];
breaks={0, x1,x2, Max[indic]};
setAvg[i_]:=Module[{idx, a},
idx=Position[indic, x_/;(x>breaks[[i]]&&x<=breaks[[i+1]])];
a=Mean[Extract[values,idx]];
avgVal=ReplacePart[avgVal, idx -> a]
];
setAvg /@ Range[1,3];
Return[avgVal];
];
myfun[20,50] (* averages values where indic < 20, between 20 and 50 and >50 *)
Minimal example:
indic = {2,3,5,6,3,6,7,4};
values = Range[3,10];
x1=3;
x2=6;
Hence group 1 is the first, second, fifth element, group 2 comprises the third and the last element, and group 3 are the remaining elements.
The mean of group 1 is Mean[3,4,7]= 14/3, of group 2 is Mean[5,10]=15/2 and of group 3 the mean is Mean[6,8,9]=23/3. That is why myfun[x1,x2] should return
{14/3, 14/3, 15/2, 23/3, 14/3, 23/3, 23/3, 15/2}
I would like to discuss how to make this code faster. Is there a more Mathematica-like way to do it? Especially, I suspect the ReplacePart
calls to be slow. Is there a way around it?
Any hint appreciated!
{Pick[values, indic, x_ /; 0 < x < 3], Pick[values, indic, x_ /; 3 < x < 6]}
. It's unclear what to do about the boundaries x1, x2, and what to do with the result, without the reverse-engineering Yves mentions. $\endgroup$Pick
have not heard of it until now. The problem for me is to write the average vector. Is there a way to speed this up? $\endgroup$