在Python中计算算术平均数(一种平均数)

279

在Python中是否有内置的或标准库方法可以计算数字列表的算术平均数(一种平均数)?


平均数是有歧义的 - 众数和中位数也是常用的平均数。 - jtlz2
1
模式和中位数是其他的集中趋势测量值。它们不是平均值。模式是数据集中出现最频繁的值,不一定是唯一的。中位数是代表数据点中心的值。正如问题所暗示的,有几种不同类型的平均值,但所有这些都与中位数和模式计算不同。http://www.purplemath.com/modules/meanmode.htm - Jarom
@Jarom,那个链接与您的观点不符:“平均数、中位数和众数是三种“平均数””。 - Marcelo Cantos
13个回答

288

我不知道标准库中是否有相关内容。但是,你可以使用类似以下的东西:

def mean(numbers):
    return float(sum(numbers)) / max(len(numbers), 1)

>>> mean([1,2,3,4])
2.5
>>> mean([])
0.0

在numpy中,有numpy.mean()函数。

21
一个常见的想法是认为[]的平均值为0,可以通过float(sum(l))/max(len(l),1)来实现。 - yo'
9
根据PEP 8规范,l是一个糟糕的变量名,因为它看起来太像1。此外,我会使用if l而不是if len(l) > 0。可以参考这里:https://dev59.com/o3VD5IYBdhLWcg3wNIvc - zondo
3
见上面的问题:为避免被零除(对于[]) - Simon Fakir
1
在Python 3中,您不需要调用float。此外,在我看来,对于空列表,引发ZeroDivisionError是有意义的,而不是返回0。通过这些更改,代码将变为:return sum(numbers) / len(numbers) - Solomon Ucko
8
空列表没有意义,请不要假装它们有意义。 - Marcelo Cantos
显示剩余2条评论

196

NumPy拥有一个算术平均的函数numpy.mean。使用起来非常简单:

>>> import numpy
>>> a = [1, 2, 4]
>>> numpy.mean(a)
2.3333333333333335

6
在虚拟环境中安装numpy非常困难。你应该考虑不使用这个库。 - vcarel
48
我不确定你为什么这样说。以前是有这个问题,但在过去一年多的时间里,安装numpy已经变得非常容易了。 - user227667
6
我必须赞同这个评论。我目前在OSX的virtualenv中使用numpy,完全没有问题(当前使用CPython 3.5)。 - Juan Carlos Coto
4
使用像Travis CI这样的持续集成系统,安装numpy需要额外几分钟的时间。如果您重视快速、轻便的构建,并且只需要平均值,请考虑... - Akseli Palén
2
@AkseliPalén 在Travis CI上的虚拟环境中,可以使用通过apt-get安装的numpy来使用系统站点包。即使只需要一个平均值,这也可能足够快速。 - Bengt
显示剩余4条评论

191

使用 statistics.mean 函数:

import statistics
print(statistics.mean([1,2,4])) # 2.3333333333333335

自Python 3.4起可用。 对于3.1-3.3用户,该模块的旧版本可在PyPI上使用,名称为stats。 只需将statistics更改为stats即可。


2
请注意,与其他解决方案相比,这种方法非常缓慢。比较 timeit("numpy.mean(vec))timeit("sum(vec)/len(vec)")timeit("statistics.mean(vec)") - 后者比其他方法慢得多(在我的电脑上有时超过100倍)。这似乎是由于 statistics 中的 sum 运算符实现特别精确,详见 PEPCode。不确定 statistics._sumnumpy.sum 之间性能差异巨大的原因。 - Eike P.
12
@jhin,这是因为statistics.mean试图让结果正确。它正确计算了[1e50, 1, -1e50] * 1000的平均值。 - Antti Haapala -- Слава Україні
1
statistics.mean 也可以接受一个值的生成器表达式,而所有使用 len() 作为除数的解决方案都会卡住。 - PaulMcG
自从Python 3.8版本以来,就有了更快的statistics.fmean函数。 - Mathieu Rollet

55

您甚至不需要使用numpy或scipy...

>>> a = [1, 2, 3, 4, 5, 6]
>>> print(sum(a) / len(a))
3

24
如果输入 mean([2,3]),则会得到2这个结果。注意浮点数的处理。最好使用 float(sum(l))/len(l)。更好的做法是要小心检查列表是否为空。 - Jk041
15
在Python 3中,除法运算会按预期进行:进行除法计算。 - yota
13
如果你在Python 2.2+的程序开头加入from __future__ import division,则可以实现: - spiffytech
大数和溢出怎么办? - obayhan
1
a = list()怎么样?建议的代码会导致ZeroDivisionError错误。 - 0 _
@Ioannis 这可以说是正常工作的。所有其他答案在空序列上引发错误或警告。 - wjandrea

8

使用Scipy:

import scipy;
a=[1,2,4];
print(scipy.mean(a));

38
scipy.stats.mean已经被弃用,请更新代码使用numpy.mean。 - Bengt

7

不必将其转换为浮点数,您可以采取以下措施

def mean(nums):
    return sum(nums, 0.0) / len(nums)

或者使用 lambda 函数。
mean = lambda nums: sum(nums, 0.0) / len(nums)

更新:2019-12-15

Python 3.8在 statistics 模块中添加了函数 fmean,它比 mean() 函数更快并且始终返回浮点数。

将数据转换为浮点型并计算算术平均值。

该函数比 mean() 函数运行更快,并且它始终返回浮点数。数据可以是一个 sequence 或 iterable。如果输入的数据集为空,则会引发 StatisticsError 异常。

fmean([3.5, 4.0, 5.25])

4.25

在版本 3.8 中新增。


3
from statistics import mean
avarage=mean(your_list)

例如
from statistics import mean

my_list=[5,2,3,2]
avarage=mean(my_list)
print(avarage)

结果是

3.0

2
如果您使用的是 Python >= 3.8 版本,您可以使用标准库中的 statistics 模块中引入的 fmean 函数。该函数可通过以下链接查看具体信息:fmean。请注意保留 HTML 标签。
>>> from statistics import fmean
>>> fmean([0, 1, 2, 3])
1.5

它比statistics.mean函数更快,但在进行计算前会将数据点转换为float,因此在某些特定情况下可能不太准确。
您可以在这里查看它的实现。

1
您的问题的正确答案是使用statistics.mean。但为了好玩,这里有一个版本的均值不使用len()函数,因此它(像statistics.mean)可以用于生成器,这些生成器不支持len()
from functools import reduce
from operator import truediv
def ave(seq):
    return truediv(*reduce(lambda a, b: (a[0] + b[1], b[0]), 
                           enumerate(seq, start=1), 
                           (0, 0)))

1
def avg(l):
    """uses floating-point division."""
    return sum(l) / float(len(l))

示例:

l1 = [3,5,14,2,5,36,4,3]
l2 = [0,0,0]

print(avg(l1)) # 9.0
print(avg(l2)) # 0.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接