Tính trung bình số học (một loại trung bình) trong Python


268

Có phương pháp thư viện chuẩn hoặc tích hợp trong Python để tính trung bình số học (một loại trung bình) của danh sách các số không?


Trung bình là không rõ ràng - chế độ và trung bình cũng là mức trung bình thường được sử dụng
jtlz2

Chế độ và trung vị là các biện pháp khác của xu hướng trung tâm. Chúng không phải là trung bình. Chế độ là giá trị phổ biến nhất được thấy trong một tập dữ liệu và không nhất thiết phải là duy nhất. Giá trị trung bình là giá trị đại diện cho trung tâm của các điểm dữ liệu. Như câu hỏi ngụ ý, có một vài loại trung bình khác nhau, nhưng tất cả đều khác với tính toán trung bình và chế độ. purplemath.com/modules/meanmode.htm
Jarom

@Jarom Liên kết đó không đồng ý với bạn: 'Trung bình, trung bình và chế độ là ba loại "trung bình"'
Marcelo Cantos

Câu trả lời:


285

Tôi không nhận thức được bất cứ điều gì trong thư viện tiêu chuẩn. Tuy nhiên, bạn có thể sử dụng một cái gì đó như:

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

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

Trong numpy, có numpy.mean().


20
Một điều phổ biến là xem xét rằng trung bình []0, có thể được thực hiện bằng float(sum(l))/max(len(l),1).
yo '

8
PEP 8 nói rằng đó llà một tên biến xấu vì nó trông rất giống 1. Ngoài ra, tôi sẽ sử dụng if lhơn là if len(l) > 0. Xem tại đây
zondo

1
Tại sao bạn đã gọi max?
1 -_-

3
Xem câu hỏi ở trên: Để tránh chia cho số không (cho [])
Simon Fakir

5
Danh sách trống không có ý nghĩa. Xin đừng giả vờ như họ làm.
Marcelo Cantos

193

NumPy có numpy.meannghĩa là số học. Cách sử dụng đơn giản như thế này:

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

6
numpy là một cơn ác mộng để cài đặt trong virtualenv. Bạn thực sự nên cân nhắc việc không sử dụng lib này
vcarel 22/12/14

46
@vcarel: "numpy là một cơn ác mộng khi cài đặt trong virtualenv". Tôi không chắc tại sao bạn nói điều này. Nó đã từng là trường hợp, nhưng cho năm ngoái hoặc nhiều hơn nó rất dễ dàng.

6
Tôi phải thứ hai nhận xét này. Tôi hiện đang sử dụng numpy trong virtualenv trong OSX và hoàn toàn không có vấn đề gì (hiện đang sử dụng CPython 3.5).
Juan Carlos Coto

4
Với các hệ thống tích hợp liên tục như Travis CI, việc cài đặt numpy mất thêm vài phút. Nếu xây dựng nhanh và nhẹ có giá trị với bạn, và bạn chỉ cần trung bình, hãy xem xét.
Akseli Palén 7/03/2016

2
@ AkseliPalén môi trường ảo trên Travis CI có thể sử dụng một numpy được cài đặt thông qua apt-get bằng cách sử dụng các gói trang web hệ thống . Điều này có thể đủ nhanh để sử dụng ngay cả khi người ta chỉ cần một phương tiện.
Bengt

184

Sử dụng statistics.mean:

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

Nó có sẵn kể từ Python 3.4. Đối với người dùng 3.1-3.3, phiên bản cũ của mô-đun có sẵn trên PyPI dưới tên stats. Chỉ cần thay đổi statisticsthành stats.


2
Lưu ý rằng điều này là cực kỳ chậm khi so sánh với các giải pháp khác. So sánh timeit("numpy.mean(vec)), timeit("sum(vec)/len(vec)")timeit("statistics.mean(vec)")- cái sau chậm hơn các yếu tố khác bởi một yếu tố rất lớn (> 100 trong một số trường hợp trên PC của tôi). Điều này dường như là do việc triển khai đặc biệt chính xác của sumtoán tử trong statistics, xem PEPCode . Không chắc chắn về lý do cho sự khác biệt hiệu suất lớn giữa statistics._sumnumpy.sum, mặc dù.
jhin

10
@jhin điều này là do statistics.meancố gắng để được chính xác . Nó tính toán chính xác trung bình của [1e50, 1, -1e50] * 1000.
Antti Haapala

1
statistics.meancũng sẽ chấp nhận biểu thức của các giá trị mà tất cả các giải pháp sử dụng len()cho ước số sẽ bị nghẹt.
PaulMcG

54

Bạn thậm chí không cần numpy hoặc scipy ...

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

24
sau đó có nghĩa là ([2,3]) sẽ cho 2. cẩn thận với phao. Sử dụng tốt hơn float (sum (l)) / len (l). Tốt hơn hết, hãy cẩn thận kiểm tra xem danh sách có trống không.
jesusiniesta

14
@jesusiniesta ngoại trừ trong python3, nơi phân chia thực hiện những gì nó dự định làm: chia
yota

11
Và trong Python 2.2+ nếu bạn from __future__ import divisionở đầu chương trình của mình
spiffytech

Những gì về số lượng lớn và tràn?
obayhan

Thế còn a = list()? Các mã đề xuất kết quả trong ZeroDivisionError.
Ioannis Filippidis


7

Thay vì đúc để nổi, bạn có thể làm theo

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

hoặc sử dụng lambda

mean = lambda nums: sum(nums, 0.0) / len(nums)

CẬP NHẬT: 2019-12-15

Python 3.8 đã thêm chức năng fmean vào mô-đun thống kê . Cái nào nhanh hơn và luôn trả về float.

Chuyển đổi dữ liệu thành số float và tính trung bình số học.

Điều này chạy nhanh hơn hàm mean () và nó luôn trả về một float. Dữ liệu có thể là một chuỗi hoặc lặp lại. Nếu tập dữ liệu đầu vào trống, hãy tăng StatisticsError.

fmean ([3.5, 4.0, 5.25])

4,25

Mới trong phiên bản 3.8.


2
from statistics import mean
avarage=mean(your_list)

ví dụ

from statistics import mean

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

và kết quả là

3.0

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

Ví dụ:

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

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

1
def list_mean(nums):
    sumof = 0
    num_of = len(nums)
    mean = 0
    for i in nums:
        sumof += i
    mean = sumof / num_of
    return float(mean)

0

Tôi luôn luôn avgbị bỏ qua khỏi các nội dung / stdlib vì nó đơn giản như

sum(L)/len(L) # L is some list

và bất kỳ cảnh báo nào sẽ được giải quyết trong mã người gọi để sử dụng cục bộ .

Hãy cẩn thận:

  1. kết quả không nổi: trong python2, 9/4 là 2. để giải quyết, sử dụng float(sum(L))/len(L)hoặcfrom __future__ import division

  2. chia cho số không: danh sách có thể trống. để giải quyết:

    if not L:
        raise WhateverYouWantError("foo")
    avg = float(sum(L))/len(L)

0

Câu trả lời thích hợp cho câu hỏi của bạn là sử dụng statistics.mean. Nhưng để giải trí, đây là một phiên bản có nghĩa là không sử dụng len()chức năng, vì vậy nó (như statistics.mean) có thể được sử dụng trên các máy phát điện, không hỗ trợ 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)))

-2

Những người khác đã đăng câu trả lời rất hay, nhưng một số người vẫn có thể đang tìm kiếm một cách cổ điển để tìm Nghĩa (avg), vì vậy ở đây tôi đăng bài này (mã được thử nghiệm trong Python 3.6):

def meanmanual(listt):

mean = 0
lsum = 0
lenoflist = len(listt)

for i in listt:
    lsum += i

mean = lsum / lenoflist
return float(mean)

a = [1, 2, 3, 4, 5, 6]
meanmanual(a)

Answer: 3.5
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.