40

似乎 scipy 曾经提供了一个函数mad来计算一组数字的平均绝对偏差:

http://projects.scipy.org/scipy/browser/trunk/scipy/stats/models/utils.py?rev=3473

但是,我在当前版本的 scipy 中找不到它。当然可以只从存储库中复制旧代码,但我更喜欢使用 scipy 的版本。我在哪里可以找到它,或者它已被替换或删除?

4

10 回答 10

57

[编辑] 因为这一直被低估:我知道中绝对偏差是一个更常用的统计数据,但提问者要求平均绝对偏差,这里是如何做到的:

from numpy import mean, absolute

def mad(data, axis=None):
    return mean(absolute(data - mean(data, axis)), axis)
于 2013-10-19T23:41:30.570 回答
36

对于它的价值,我将它用于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))
于 2014-05-08T07:56:02.930 回答
28

当前版本的statsmodels有:madstatsmodels.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])

请注意,默认情况下,这会通过缩放结果缩放因子来计算假设正态分布的标准偏差的稳健估计;来自help

Signature: robust.mad(a, 
                      c=0.67448975019608171, 
                      axis=0, 
                      center=<function median at 0x10ba6e5f0>)

中的版本R进行了类似的规范化。如果您不想要这个,显然只需设置c=1.

(之前的评论提到这是 in statsmodels.robust.scale。实现在statsmodels/robust/scale.py(见github)但robust包没有 export scale,而是显式地导出公共函数scale.py。)

于 2016-11-15T21:02:40.410 回答
16

由于烘焙不足,看起来 scipy.stats.models 在 2008 年 8 月被删除。开发已迁移到statsmodels.

于 2012-01-19T21:47:04.873 回答
9

如果你喜欢在Pandas中工作(就像我一样),它对平均绝对偏差有一个有用的功能

import pandas as pd
df = pd.DataFrame()
df['a'] = [1, 1, 2, 2, 4, 6, 9]
df['a'].mad()

输出:2.3673469387755106

于 2017-06-19T11:13:42.433 回答
4

这不是 scipy 版本,但这里是使用掩码数组忽略错误值的 MAD 实现: http ://code.google.com/p/agpy/source/browse/trunk/agpy/mad.py

编辑:这里有更新的版本。

编辑 2:这里还有一个 astropy 版本。

于 2013-02-25T17:33:38.960 回答
4

仅使用numpy

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)
于 2018-01-10T19:19:57.003 回答
3

我正在使用:

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
于 2014-04-21T16:21:50.803 回答
3

我只是在学习 Python 和 Numpy,但这是我为检查我 7 年级学生的数学作业而编写的代码,该作业需要 2 组数字的 M(ean)AD:

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]])

Numpy 一维数组中的数据:

>>> 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)
于 2016-05-05T05:17:43.180 回答
1

不想被误导,疯子现在在 scipy.stats:https ://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.median_absolute_deviation.html

于 2020-12-09T20:59:29.150 回答