Il semble que scipy ait fourni une fonction mad
pour calculer l'écart absolu moyen pour un ensemble de nombres:
http://projects.scipy.org/scipy/browser/trunk/scipy/stats/models/utils.py?rev=347
Cependant, je ne le trouve nulle part dans les versions actuelles de scipy. Bien sûr, il est possible de simplement copier l'ancien code du référentiel mais je préfère utiliser la version de scipy. Où puis-je le trouver, ou a-t-il été remplacé ou supprimé?
La version actuelle de statsmodels a mad
in statsmodels.robust
:
>>> import numpy as np
>>> from statsmodels import robust
>>> a = np.matrix( [
... [ 80, 76, 77, 78, 79, 81, 76, 77, 79, 84, 75, 79, 76, 78 ],
... [ 66, 69, 76, 72, 79, 77, 74, 77, 71, 79, 74, 66, 67, 73 ]
... ], dtype=float )
>>> robust.mad(a, axis=1)
array([ 2.22390333, 5.18910776])
Notez que par défaut, cela calcule l'estimation robuste de l'écart-type en supposant une distribution normale en mettant à l'échelle le résultat un facteur de mise à l'échelle; de help
:
Signature: robust.mad(a,
c=0.67448975019608171,
axis=0,
center=<function median at 0x10ba6e5f0>)
La version dans R
fait une normalisation similaire. Si vous ne le souhaitez pas, il suffit évidemment de définir c=1
.
(Un commentaire précédent mentionnait que c'était dans statsmodels.robust.scale
. L'implémentation est en statsmodels/robust/scale.py
(voir github ) mais le package robust
n'exporte pas scale
, il exporte plutôt les fonctions publiques dans scale.py
explicitement.)
[EDIT] Étant donné que cela continue de faire l'objet d'un vote négatif: je sais que médiane écart absolu est une statistique plus couramment utilisée, mais le questionneur a demandé moyenne écart absolu, et voici comment pour le faire:
from numpy import mean, absolute
def mad(data, axis=None):
return mean(absolute(data - mean(data, axis)), axis)
Pour ce que ça vaut, je l'utilise pour MAD:
def mad(arr):
""" Median Absolute Deviation: a "Robust" version of standard deviation.
Indices variabililty of the sample.
https://en.wikipedia.org/wiki/Median_absolute_deviation
"""
arr = np.ma.array(arr).compressed() # should be faster to not use masked arrays.
med = np.median(arr)
return np.median(np.abs(arr - med))
Il semble que scipy.stats.models était supprimé en août 2008 en raison d'une cuisson insuffisante. Le développement a migré vers statsmodels
.
Si vous aimez travailler dans Pandas (comme moi), il a une fonction utile pour l'écart absolu moyen :
import pandas as pd
df = pd.DataFrame()
df['a'] = [1, 1, 2, 2, 4, 6, 9]
df['a'].mad()
Sortie: 2.3673469387755106
Ce n'est pas la version scipy, mais voici une implémentation du MAD utilisant des tableaux masqués pour ignorer les mauvaises valeurs: http://code.google.com/p/agpy/source/browse/trunk/agpy/mad.py
Edit: Une version plus récente est disponible ici .
Edit 2: Il existe également une version en astropie ici .
J'utilise:
from math import fabs
a = [1, 1, 2, 2, 4, 6, 9]
median = sorted(a)[len(a)//2]
for b in a:
mad = fabs(b - median)
print b,mad
Utilisation de numpy
uniquement:
def meanDeviation(numpyArray):
mean = np.mean(numpyArray)
f = lambda x: abs(x - mean)
vf = np.vectorize(f)
return (np.add.reduce(vf(numpyArray))) / len(numpyArray)
J'apprends juste Python et Numpy, mais voici le code que j'ai écrit pour vérifier les devoirs de mathématiques de ma 7e niveleuse qui voulait le M (ean) AD de 2 ensembles de nombres:
Données dans les lignes de la matrice Numpy:
import numpy as np
>>> a = np.matrix( [ [ 80, 76, 77, 78, 79, 81, 76, 77, 79, 84, 75, 79, 76, 78 ], \\
... [ 66, 69, 76, 72, 79, 77, 74, 77, 71, 79, 74, 66, 67, 73 ] ], dtype=float )
>>> matMad = np.mean( np.abs( np.tile( np.mean( a, axis=1 ), ( 1, a.shape[1] ) ) - a ), axis=1 )
>>> matMad
matrix([[ 1.81632653],
[ 3.73469388]])
Données dans les tableaux Numpy 1D:
>>> a1 = np.array( [ 80, 76, 77, 78, 79, 81, 76, 77, 79, 84, 75, 79, 76, 78 ], dtype=float )
>>> a2 = np.array( [ 66, 69, 76, 72, 79, 77, 74, 77, 71, 79, 74, 66, 67, 73 ], dtype=float )
>>> madA1 = np.mean( np.abs( np.tile( np.mean( a1 ), ( 1, len( a1 ) ) ) - a1 ) )
>>> madA2 = np.mean( np.abs( np.tile( np.mean( a2 ), ( 1, len( a2 ) ) ) - a2 ) )
>>> madA1, madA2
(1.816326530612244, 3.7346938775510199)