7

I want to calculate the weighted mean of a set of angles.

In this Question, there's an answer how to calculate the mean as shown in this page.

Now I'm trying to figure out how to calculate the weighted average. That is, for each angle there is a weight (the weights sum up to 1)

0.25, 0 degrees 0.5, 20 degrees 0.25, 90 degrees

The weighted avg should (if I didn't make a mistake) be 32 degrees.

Community
  • 1
  • 1
Chris
  • 1,133
  • 7
  • 14

2 Answers2

7

OK, my attemp was to just multiply the values with the weights:

def circular_mean(weights, angles):
    x = y = 0.
    for angle, weight in zip(angles, weights):
        x += math.cos(math.radians(angle)) * weight
        y += math.sin(math.radians(angle)) * weight

    mean = math.degrees(math.atan2(y, x))
    return mean

It SEEMS to work correct. I have to think of good test data.

Chris
  • 1,133
  • 7
  • 14
  • 2
    you have to check for (x,y) = (0,0), in this case the average direction is not defined – fa. Nov 06 '09 at 12:02
  • +1: This is effectively the vector sum, where the vector length is the weight. Imho, this makes the most sense for a weakly defined problem. Otherwise, would you want the weight=.5, A=359.99 to be an angle of about 180? – tom10 Nov 06 '09 at 16:06
1

Depending on your application the question has different answers. As mentioned above you may need to normalize your values and you may need to have signed angles, or you may not wish to. Unless you know what the angle generating function is there may not be a unique answer.

This was a sufficient problem for me (working in geometry) I wrote my own Angle class.

peter.murray.rust
  • 37,407
  • 44
  • 153
  • 217