import numpy as np
# solution 1 avec les cosinus directeurs
# --------------------------------------
from collections import namedtuple
def cosdir_azim(azim):
az = np.radians(azim)
cosa =np.sin(az)
cosb = np.cos(az)
name = namedtuple("name", ["cosa", "cosb"])
return name(cosa,cosb)
angles = np.array([341.0, 359.0, 334.0, 15.0, 330.0, 301.0, 299.0, 9.0, 7.0, 353.0, 28.0, 25.0, 23.0, 30.0, 350.0, 25.0, 22.0, 8.0, 356.0, 27.0])
sommecosa = sum(cosdir_azim(angles).cosa)
sommecosb = sum(cosdir_azim(angles).cosb)
# direction moyenne angulaire
print "{:.6f}".format(np.degrees(np.arctan2(sommecosa,sommecosb)))
1.060902
# longueur résultante moyenne
print "{:.6f}".format(np.sqrt(sommecosa*sommecosa + sommecosb*sommecosb)/len(angles))
0.896237
# variance angulaire
print 1 - np.sqrt(sommecosa*sommecosa + sommecosb*sommecosb)/len(angles)
0.103763188613
# ou directement
def getCircularMean(angles):
n = len(angles)
sineMean = np.divide(np.sum(np.sin(np.radians(angles))), n)
cosineMean = np.divide(np.sum(np.cos(np.radians(angles))), n)
vectorMean = np.arctan2(sineMean, cosineMean)
return np.degrees(vectorMean)
print "{:.6f}".format(getCircularMean(angles))
1.060902
# solution 2 avec SciPy
# ---------------------
from scipy import stats
T1 = np.radians(np.array(angles))
# direction moyenne angulaire
print "{:.6f}".format(np.degrees(stats.circmean(T1)))
1.060902
# solution 3 avec pycircstat
# ---------------------------
import pycircstat
T1 = np.radians(np.array(angles))
# direction moyenne angulaire
print "{:.6f}".format(np.degrees(np.array(pycircstat.mean(T1))))
1.060902
# longueur résultante moyenne
print "{:.6f}".format(pycircstat.resultant_vector_length(T1))
0.896237
# variance angulaire
1 - pycircstat.resultant_vector_length(T1
0.1037632
# variance angulaire selon Batschelet (1981) = 2 * (1 - R)
print "{:.6f}".format(pycircstat.avar(T1))
0.207526
# déviation angulaire standard
print "{:.6f}".format(pycircstat.std(T1))
0.468082