5
$\begingroup$

I have three lists:

data = {1,0,0,0,1,0,1,0};
time = {1,1,1,1,4,4,4,4};
weight = {0.5,0.5,0.5,0.3,0.5,0.6,0.7,0.8};

data represents a data points that were recorded at the instance given by the vector time. Each recording has a specific weight attached to it, given in the weight vector.

The question

I would like to calculate for every time step.

{1,1,1,1 ...} -> is one time step (multiple recordings),

{...,4,4,4,4} -> is another time step

...the weighted mean of the data.

How can I do it with Mathematica? I need to have a scalable solution, since I will incorporate multiple data.

I was thinking about using:

WeightedData[data, weight] to calculate the weighted data.

$\endgroup$

5 Answers 5

6
$\begingroup$

Here's one way. There will be many more!

{#[[1, 1]], Mean[WeightedData[#[[;; , 2]], #[[;; , 3]]]]} & /@ GatherBy[Transpose[{time, data, weight}], First]

Another:

GroupBy[{time, data, weight}\[Transpose], First -> Rest, Mean@*Apply[WeightedData]@*Transpose]
$\endgroup$
1
  • $\begingroup$ Really nice use of GroupBy +1 !! $\endgroup$
    – Ali Hashmi
    May 9, 2017 at 16:10
4
$\begingroup$
Merge[Mean@*Apply[WeightedData]@*Transpose]@ Thread[time -> {data, weight}\[Transpose]]
$\endgroup$
0
2
$\begingroup$
GroupBy[Transpose[{time, weight, data * weight}], First, 
(Total[#[[;; , -1]]]/Total[#[[;; , 2]]]) &]

<|1 -> 0.277778, 4 -> 0.461538|>

$\endgroup$
0
1
$\begingroup$

Using Dataset:

ds = Transpose@Dataset@AssociationMap[Symbol, {"data", "time", "weight"}]

ds[GroupBy["time"], Mean@WeightedData[#[[All, "data"]], #[[All, "weight"]]] &]

(*OR*)

ds[GroupBy["time"], Transpose][All, Mean@WeightedData[#data, #weight] &]

enter image description here

Another way, without Transpose:

ds = Dataset@AssociationMap[Symbol, {"data", "time", "weight"}];
ds["time", PositionIndex][All, ds[All, #][Mean@WeightedData[#data, #weight] &] &]
$\endgroup$
0
0
$\begingroup$
MapThread[#1 -> Mean@*Apply[WeightedData]@Transpose[#2] &, {Union @@ #1, 
Partition[{data, weight}\[Transpose], Sequence @@ Map[Length]@#]}] &@GatherBy[time]

(* {1 -> 0.277778, 4 -> 0.461538} *)
$\endgroup$
2
  • $\begingroup$ @DoHe you can upvote answers you find useful in order to express your appreciation. No need to thank everyone around :) Please take a tour $\endgroup$
    – Kuba
    May 9, 2017 at 20:45
  • $\begingroup$ @Kuba, okay thanks for the note ! $\endgroup$
    – henry
    May 10, 2017 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.