Tìm mức trung bình của một danh sách


473

Tôi phải tìm trung bình của một danh sách trong Python. Đây là mã của tôi cho đến nay

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print reduce(lambda x, y: x + y, l)

Tôi đã có nó để nó cộng các giá trị trong danh sách lại với nhau, nhưng tôi không biết làm thế nào để phân chia chúng thành các giá trị?


45
numpy.mean nếu bạn có đủ khả năng cài đặt numpy
mitch

7
sum(L) / float(len(L)). xử lý danh sách trống trong mã người gọi nhưif not L: ...
n611x007

4
@mitch: vấn đề không phải là bạn có đủ khả năng cài đặt numpy hay không. numpy là một từ toàn bộ trong chính nó. Đó là cho dù bạn thực sự cần numpy. Cài đặt numpy, một phần mở rộng 16mb C, để tính toán có nghĩa là, rất, không thực tế, cho một người không sử dụng nó cho những thứ khác.
n611x007

3
thay vì cài đặt toàn bộ gói numpy cho avg / mean nếu sử dụng python 3, chúng ta có thể thực hiện điều này bằng cách sử dụng mô-đun thống kê chỉ bằng "từ trung bình nhập khẩu thống kê" hoặc nếu trên python 2.7 trở xuống, mô-đun thống kê có thể được tải xuống từ src: hg.python.org/cpython/file/default/Lib/statistics.py doc: docs.python.org/dev/library/statistics.html và trực tiếp sử dụng.
25mhz

Câu trả lời:


568

Trên Python 3.4+ bạn có thể sử dụng statistics.mean()

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import statistics
statistics.mean(l)  # 20.11111111111111

Trên các phiên bản cũ hơn của Python, bạn có thể làm

sum(l) / len(l)

Trên Python 2, bạn cần chuyển đổi lenthành float để có phân chia float

sum(l) / float(len(l))

Không có nhu cầu sử dụng reduce. Nó chậm hơn nhiều và đã bị xóa trong Python 3.


9
nếu danh sách gồm ints, các kết quả dưới python 2 sẽ là một int
Mitch

Thật hoàn hảo! xin lỗi vì câu hỏi ngu ngốc, nhưng tôi thực sự đã tìm mọi nơi vì điều đó! cảm ơn bạn rất nhiều !
Carla Dessi

7
Như tôi đã nói, tôi mới biết điều này, tôi đã nghĩ rằng tôi phải làm nó bằng một vòng lặp hoặc một cái gì đó để đếm số lượng số trong đó, tôi không nhận ra mình chỉ có thể sử dụng độ dài. đây là điều đầu tiên tôi làm với trăn ..
Carla Dessi

2
Điều gì xảy ra nếu tổng là một số lượng lớn không phù hợp với int / float?
Người dùng Foo Bar

5
@FooBarUser thì bạn nên calc k = 1.0 / len (l), sau đó giảm: giảm (lambda x, y: x + y * k, l)
Arseniy

519
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
sum(l) / len(l)

63
Nếu bạn sử dụng from __future__ import division, bạn có thể loại bỏ sự xấu xí đó float.
S.Lott

12
Đã đồng ý. floatxấu như địa ngục, chỉ muốn giữ nó đơn giản hơn.
yprez

39
Một cách khác để loại bỏ sự nổi "xấu xí" đó:sum(l, 0.0) / len(l)
remosu

26
Là một lập trình viên C ++, điều đó gọn gàng như địa ngục và nổi không hề xấu xí chút nào!
lahjaton_j

20
Trong python3, bạn chỉ có thể sử dụngsum(l) / len(l)
VasiliNovikov

283

Bạn có thể sử dụng numpy.mean:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import numpy as np
print(np.mean(l))

4
Điều đó thật lạ. Tôi đã cho rằng việc này sẽ hiệu quả hơn nhiều, nhưng dường như mất gấp 8 lần trong một danh sách phao ngẫu nhiên hơn là đơn giảnsum(l)/len(l)
L. Amber O'Hearn

8
Oh, nhưng np.array(l).mean()nhiều nhanh hơn.
L. Amber O'Hearn

8
@ L <berO'Hearn, tôi chỉ hẹn giờ np.mean(l)np.array(l).meancó cùng tốc độ, và sum(l)/len(l)nhanh gấp đôi. Tôi đã sử dụng l = list(np.random.rand(1000)), tất nhiên cả hai numpyphương pháp trở nên nhanh hơn nhiều nếu lnumpy.array.
Akavall

11
tốt, trừ khi đó là lý do duy nhất để cài đặt numpy. cài đặt gói 16mb C của bất kỳ danh tiếng nào để tính toán trung bình trông rất lạ trên thang đo này.
n611x007

nhưng trong tâm trí của tôi. không cần quan tâm đến tốc độ trong điều kiện bình thường ..
tyan

230

Một mô-đun thống kê đã được thêm vào python 3.4 . Nó có một hàm để tính giá trị trung bình gọi là trung bình . Một ví dụ với danh sách bạn cung cấp sẽ là:

from statistics import mean
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
mean(l)

28
Đây là câu trả lời tao nhã nhất vì nó sử dụng một mô-đun thư viện tiêu chuẩn có sẵn từ python 3.4.
Serge Stroobandt

4
Và đó là stabler số
Antti Haapala

Và nó tạo ra một lỗi đẹp hơn nếu bạn vô tình chuyển vào một danh sách trống statistics.StatisticsError: mean requires at least one data pointthay vì khó hiểu hơn ZeroDivisionError: division by zerocho sum(x) / len(x)giải pháp.
Boris

45

Tại sao bạn sẽ sử dụng reduce()cho điều này khi Python có sum()chức năng cromulent hoàn hảo ?

print sum(l) / float(len(l))

(Điều float()cần thiết là buộc Python thực hiện phép chia dấu phẩy động.)


34
Đối với những người trong chúng ta mới biết đến từ 'cromulent'
RolfBly

1
float()không cần thiết trên Python 3.
Boris

36

Có thư viện thống kê nếu bạn đang sử dụng python> = 3,4

https://docs.python.org/3/l Library / statistic.html

Bạn có thể sử dụng phương pháp của nó như thế này. Giả sử bạn có một danh sách các số mà bạn muốn tìm có nghĩa là: -

list = [11, 13, 12, 15, 17]
import statistics as s
s.mean(list)

Nó có các phương thức khác giống như stdev, phương sai, chế độ, trung bình hài, trung vị, v.v ... quá hữu ích.


18

Thay vì truyền để nổi, bạn có thể thêm 0,0 vào tổng:

def avg(l):
    return sum(l, 0.0) / len(l)

10

sum(l) / float(len(l)) là câu trả lời đúng, nhưng chỉ cần tính đầy đủ, bạn có thể tính trung bình với một mức giảm duy nhất:

>>> reduce(lambda x, y: x + y / float(len(l)), l, 0)
20.111111111111114

Lưu ý rằng điều này có thể dẫn đến một lỗi làm tròn nhẹ:

>>> sum(l) / float(len(l))
20.111111111111111

Tôi hiểu rằng đây chỉ là để giải trí nhưng trả về 0 cho một danh sách trống có thể không phải là điều tốt nhất để làm
Johan Lundberg

1
@JohanLundberg - Bạn có thể thay thế 0 bằng Sai làm đối số cuối cùng reduce()sẽ cung cấp cho bạn Sai cho danh sách trống, nếu không thì trung bình như trước.
Andrew Clark

@AndrewClark tại sao bạn buộc floattrên len?
EndermanAPM

8

Tôi đã thử sử dụng các tùy chọn ở trên nhưng không được. Thử cái này:

from statistics import mean

n = [11, 13, 15, 17, 19]

print(n)
print(mean(n))

làm việc trên python 3.5


6

Hoặc sử dụng pandascủa Series.meanphương pháp:

pd.Series(sequence).mean()

Bản giới thiệu:

>>> import pandas as pd
>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> pd.Series(l).mean()
20.11111111111111
>>> 

Từ các tài liệu:

Series.mean(axis=None, skipna=None, level=None, numeric_only=None, **kwargs)

Và đây là tài liệu cho việc này:

https://pandas.pydata.org/pandas-docs/urdy/generated/pandas.Series.mean.html

Và toàn bộ tài liệu:

https://pandas.pydata.org/pandas-docs/urdy/10min.html


Đây không phải là một câu hỏi về gấu trúc, vì vậy có vẻ quá nhiều khi nhập một thư viện nặng như vậy cho một hoạt động đơn giản như tìm giá trị trung bình.
cs95

4

Tôi đã có một câu hỏi tương tự để giải quyết vấn đề của Udacity. Thay vì một hàm tích hợp, tôi đã mã hóa:

def list_mean(n):

    summing = float(sum(n))
    count = float(len(n))
    if n == []:
        return False
    return float(summing/count)

Lâu hơn nhiều so với bình thường nhưng đối với người mới bắt đầu thì khá khó khăn.


1
Tốt Mọi câu trả lời khác đều không nhận thấy mối nguy trong danh sách trống!
wsysuper

1
Trả về False(tương đương với số nguyên 0) chỉ là cách tồi tệ nhất có thể để xử lý lỗi này. Tốt hơn để bắt ZeroDivisionErrorvà nâng cao một cái gì đó tốt hơn (có lẽ ValueError).
loại

@kindall thế nào là ValueErrortốt hơn a ZeroDivisionError? Cái sau cụ thể hơn, cộng với có vẻ hơi không cần thiết khi bắt lỗi số học chỉ để ném lại một lỗi khác.
MatTheWhale

Bởi vì ZeroDivisionErrorchỉ hữu ích nếu bạn biết cách tính toán được thực hiện (nghĩa là có chia cho độ dài của danh sách). Nếu bạn không biết điều đó, nó sẽ không cho bạn biết vấn đề là gì với giá trị bạn đã truyền vào. Trong khi đó, ngoại lệ mới của bạn có thể bao gồm thông tin cụ thể hơn đó.
18 giờ 34 phút

4

là người mới bắt đầu, tôi chỉ mã hóa điều này:

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

total = 0

def average(numbers):
    total = sum(numbers)
    total = float(total)
    return total / len(numbers)

print average(L)

Bravo: IMHO, sum(l)/len(l)cho đến nay là câu trả lời thanh lịch nhất (không cần thực hiện chuyển đổi loại trong Python 3).
fralau

4

Nếu bạn muốn nhận được nhiều hơn chỉ là trung bình (còn gọi là trung bình), bạn có thể kiểm tra số liệu thống kê đáng sợ

from scipy import stats
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(stats.describe(l))

# DescribeResult(nobs=9, minmax=(2, 78), mean=20.11111111111111, 
# variance=572.3611111111111, skewness=1.7791785448425341, 
# kurtosis=1.9422716419666397)

3

Để sử dụng reduceđể lấy mức trung bình đang chạy, bạn sẽ cần theo dõi tổng số nhưng cũng có tổng số phần tử được nhìn thấy cho đến nay. vì đó không phải là một yếu tố tầm thường trong danh sách, bạn cũng sẽ phải thông qua reducemột đối số bổ sung để xếp vào.

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> running_average = reduce(lambda aggr, elem: (aggr[0] + elem, aggr[1]+1), l, (0.0,0))
>>> running_average[0]
(181.0, 9)
>>> running_average[0]/running_average[1]
20.111111111111111

1
thú vị nhưng đó không phải là những gì anh ấy yêu cầu.
Johan Lundberg

3

Cả hai đều có thể cung cấp cho bạn gần với các giá trị tương tự trên một số nguyên hoặc ít nhất 10 giá trị thập phân. Nhưng nếu bạn thực sự xem xét các giá trị nổi dài cả hai có thể khác nhau. Cách tiếp cận có thể khác nhau về những gì bạn muốn đạt được.

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> print reduce(lambda x, y: x + y, l) / len(l)
20
>>> sum(l)/len(l)
20

Giá trị nổi

>>> print reduce(lambda x, y: x + y, l) / float(len(l))
20.1111111111
>>> print sum(l)/float(len(l))
20.1111111111

@Andrew Clark đã đúng về tuyên bố của mình.


3

giả sử rằng

x = [[-5.01,-5.43,1.08,0.86,-2.67,4.94,-2.51,-2.25,5.56,1.03], [-8.12,-3.48,-5.52,-3.78,0.63,3.29,2.09,-2.13,2.86,-3.33], [-3.68,-3.54,1.66,-4.11,7.39,2.08,-2.59,-6.94,-2.26,4.33]]

bạn có thể nhận thấy rằng xcó kích thước 3 * 10 nếu bạn cần lấy meantừng hàng, bạn có thể nhập thứ này

theMean = np.mean(x1,axis=1)

đừng quên import numpy as np


1
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

l = map(float,l)
print '%.2f' %(sum(l)/len(l))

3
Không hiệu quả. Nó chuyển đổi tất cả các yếu tố để nổi trước khi thêm chúng. Nó nhanh hơn để chuyển đổi chiều dài.
Chris Koston

1

Tìm mức trung bình trong danh sách Bằng cách sử dụng mã PYTHON sau :

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(sum(l)//len(l))

Hãy thử nó dễ dàng.


0
print reduce(lambda x, y: x + y, l)/(len(l)*1.0)

hoặc thích đăng trước đó

sum(l)/(len(l)*1.0)

1.0 là để đảm bảo bạn có được phân chia dấu phẩy động


0

Kết hợp một vài câu trả lời ở trên, tôi đã đưa ra những cách sau đây có tác dụng giảm và không cho rằng bạn có Lsẵn bên trong hàm khử:

from operator import truediv

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

def sum_and_count(x, y):
    try:
        return (x[0] + y, x[1] + 1)
    except TypeError:
        return (x + y, 2)

truediv(*reduce(sum_and_count, L))

# prints 
20.11111111111111

0

Tôi muốn thêm một cách tiếp cận khác

import itertools,operator
list(itertools.accumulate(l,operator.add)).pop(-1) / len(l)

-5
numbers = [0,1,2,3]

numbers[0] = input("Please enter a number")

numbers[1] = input("Please enter a second number")

numbers[2] = input("Please enter a third number")

numbers[3] = input("Please enter a fourth number")

print (numbers)

print ("Finding the Avarage")

avarage = int(numbers[0]) + int(numbers[1]) + int(numbers[2]) + int(numbers [3]) / 4

print (avarage)

Nếu người dùng thêm số dấu phẩy động vào mảng của bạn thì sao? Kết quả sẽ siêu không chính xác.
Flame_Phoenix
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.