การหาค่าเฉลี่ยของรายการ


473

ฉันต้องค้นหาค่าเฉลี่ยของรายการใน Python นี่คือรหัสของฉันจนถึงตอนนี้

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

ฉันได้มันมาแล้วมันจะรวมค่าต่าง ๆ ในรายการเข้าด้วยกัน แต่ฉันไม่รู้ว่าจะแบ่งมันเป็นอย่างไร


45
numpy.mean ถ้าคุณสามารถจ่ายได้ที่จะติดตั้ง numpy
mitch

7
sum(L) / float(len(L)). จัดการรายการว่างในรหัสผู้โทรเช่นif not L: ...
n611x007

4
@mitch: มันไม่สำคัญว่าคุณจะสามารถติดตั้งจำนวนมากได้หรือไม่ numpy เป็นคำทั้งหมดในตัวเอง ไม่ว่าคุณจะต้องการความเป็นจริงหรือไม่ การติดตั้ง numpy, ส่วนขยาย 16mb C, สำหรับการคำนวณค่าเฉลี่ยน่าจะเป็นไปได้มาก, สำหรับคนที่ไม่ได้ใช้มันสำหรับสิ่งอื่น ๆ
n611x007

3
แทนที่จะติดตั้งแพคเกจ numpy ทั้งหมดเพียงแค่ avg / mean ถ้าใช้ python 3 เราสามารถทำสิ่งนี้ได้โดยใช้โมดูลสถิติโดย "จากสถิติการนำเข้าเฉลี่ย" หรือบน python 2.7 หรือน้อยกว่านั้นโมดูลสถิติสามารถดาวน์โหลดได้จาก src: hg.python.org/cpython/file/default/Lib/statistics.py doc: docs.python.org/dev/library/statistics.html และใช้โดยตรง
25 เมกะเฮิรตซ์

2
มีความเป็นไปได้ที่ซ้ำกันของการคำนวณค่าเฉลี่ยเลขคณิต (ค่าเฉลี่ย) ใน Python
Pale Blue Dot

คำตอบ:


567

บน Python 3.4+ คุณสามารถใช้ได้ statistics.mean()

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

import statistics
statistics.mean(l)  # 20.11111111111111

ใน Python เวอร์ชันเก่ากว่าคุณสามารถทำได้

sum(l) / len(l)

ใน Python 2 คุณจะต้องแปลงlenเป็นทศนิยมเพื่อให้ได้ค่าทศนิยม

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

reduceไม่มีความจำเป็นที่จะใช้เป็น มันช้ากว่ามากและถูกลบใน Python 3


9
หากรายการประกอบด้วย ints ผลลัพธ์ภายใต้ python 2 จะเป็น int
mitch

มันสมบูรณ์แบบ! ขอโทษสำหรับคำถามที่โง่ แต่ฉันได้ดูทุกที่อย่างแท้จริง! ขอบคุณมาก !
Carla Dessi

7
อย่างที่ฉันพูดฉันยังใหม่กับสิ่งนี้ฉันคิดว่าฉันต้องทำมันด้วยการวนซ้ำหรือบางอย่างเพื่อนับจำนวนตัวเลขในนั้นฉันไม่ได้ตระหนักว่าฉันสามารถใช้ความยาวได้ นี่คือสิ่งแรกที่ผมทำกับงูหลาม ..
คาร์ล่า Dessi

2
แล้วถ้าผลรวมเป็นจำนวนมากที่ไม่เข้ากับ int / float ล่ะ?
ผู้ใช้ Foo Bar

5
@FooBarUser จากนั้นคุณควรคำนวณ k = 1.0 / len (l) และลด: ลด (แลมบ์ดา x, y: x + y * k, l)
Arseniy

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

63
ถ้าคุณใช้คุณสามารถกำจัดที่น่าเกลียดfrom __future__ import division float
S.Lott

12
ตกลง floatมันน่าเกลียดเหมือนนรกแค่อยากให้มันง่ายขึ้น
yprez

39
อีกวิธีในการกำจัดทุ่นลอย 'น่าเกลียด':sum(l, 0.0) / len(l)
remosu

26
ในฐานะโปรแกรมเมอร์ C ++ นั่นเป็นระเบียบเหมือนนรกและลอยไม่น่าเกลียดเลย!
lahjaton_j

20
ใน python3 คุณสามารถใช้sum(l) / len(l)
VasiliNovikov

283

คุณสามารถใช้numpy.mean:

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

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

4
มันแปลกมาก ฉันจะสันนิษฐานว่านี่จะมีประสิทธิภาพมากขึ้น แต่ดูเหมือนว่าจะใช้เวลา 8 ครั้งในการสุ่มรายการของการลอยตัวมากกว่าเพียงแค่sum(l)/len(l)
L. Amber O'Hearn

8
โอ้ แต่np.array(l).mean()เป็นมากได้เร็วขึ้น
L. Amber O'Hearn

8
@ L.AmberO'Hearn ผมก็หมดเวลาแล้วnp.mean(l)และnp.array(l).meanที่เกี่ยวกับความเร็วเดียวกันและsum(l)/len(l)เป็นเรื่องเกี่ยวกับสองครั้งที่รวดเร็ว ผมใช้l = list(np.random.rand(1000))สำหรับการเรียนการสอนทั้งnumpyวิธีการกลายเป็นเร็วถ้ามีl numpy.array
Akavall

11
ดีเว้นแต่ว่าเป็นเหตุผลเดียวสำหรับการติดตั้ง numpy การติดตั้งแพ็คเกจ 16mb C ของสิ่งที่มีชื่อเสียงสำหรับการคำนวณค่าเฉลี่ยดูแปลกมากในระดับนี้
n611x007

แต่ใน mind.there ของฉันไม่จำเป็นต้องดูแลเกี่ยวกับความเร็วในสภาพปกติ ..
TYAN

230

สถิติโมดูลได้รับการเพิ่มหลาม 3.4 มันมีฟังก์ชั่นในการคำนวณค่าเฉลี่ยที่เรียกว่าค่าเฉลี่ย ตัวอย่างของรายการที่คุณให้ไว้คือ:

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

28
นี่เป็นคำตอบที่ดีที่สุดเพราะใช้โมดูลไลบรารี่มาตรฐานซึ่งมีให้ตั้งแต่ python 3.4
Serge Stroobandt

4
และมันก็เป็นตัวทำให้ตัวเลขเป็นจำนวนมาก
Antti Haapala

และจะสร้างข้อผิดพลาดที่ดีกว่าถ้าคุณบังเอิญผ่านรายการที่ว่างเปล่าstatistics.StatisticsError: mean requires at least one data pointแทนที่จะเป็นความลับเพิ่มเติมZeroDivisionError: division by zeroสำหรับการsum(x) / len(x)แก้ปัญหา
บอริส

45

ทำไมคุณจะใช้reduce()สิ่งนี้เมื่องูหลามมีsum()ฟังก์ชั่นcromulent อย่างสมบูรณ์แบบ?

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

( float()จำเป็นต้องบังคับให้ Python ทำการแบ่งทศนิยม)


34
สำหรับพวกเราใหม่ต่อคำว่า'cromulent'
RolfBly

1
float()ไม่จำเป็นใน Python 3
Boris

36

มีไลบรารีสถิติหากคุณใช้งาน python> = 3.4

https://docs.python.org/3/library/statistics.html

คุณอาจใช้วิธีการแบบนี้ สมมติว่าคุณมีรายการตัวเลขที่คุณต้องการหาค่าเฉลี่ย: -

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

มันมีวิธีอื่น ๆ เช่น stdev, แปรปรวน, โหมด, ค่าเฉลี่ยฮาร์มอนิก, ค่ามัธยฐาน ฯลฯ ซึ่งมีประโยชน์มากเกินไป



10

sum(l) / float(len(l)) เป็นคำตอบที่ถูกต้อง แต่เพื่อความสมบูรณ์คุณสามารถคำนวณค่าเฉลี่ยด้วยการลดครั้งเดียว:

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

โปรดทราบว่าสิ่งนี้อาจทำให้เกิดข้อผิดพลาดในการปัดเศษเล็กน้อย:

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

ฉันจะได้รับว่านี้เป็นเพียงเพื่อความสนุกสนาน แต่กลับ 0 สำหรับรายการที่ว่างเปล่าไม่อาจจะเป็นสิ่งที่ดีที่สุดที่จะทำ
โยฮัน Lundberg

1
@JohanLundberg - คุณสามารถแทนที่ 0 ด้วยเท็จเป็นอาร์กิวเมนต์สุดท้ายreduce()ที่จะให้เท็จสำหรับรายการที่ว่างเปล่ามิฉะนั้นค่าเฉลี่ยเหมือนก่อน
แอนดรูคลาร์ก

@AndrewClark ทำไมคุณบังคับfloatเมื่อวันที่len?
EndermanAPM

8

ฉันลองใช้ตัวเลือกด้านบน แต่ไม่ได้ผล ลองสิ่งนี้:

from statistics import mean

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

print(n)
print(mean(n))

ทำงานบนหลาม 3.5


6

หรือการใช้pandas's Series.meanวิธีการ:

pd.Series(sequence).mean()

การสาธิต:

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

จากเอกสาร:

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

และนี่คือเอกสารสำหรับสิ่งนี้:

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

และเอกสารทั้งหมด:

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


นี่ไม่ใช่คำถามหมีแพนด้าดังนั้นจึงดูเหมือนว่าจะนำเข้าห้องสมุดขนาดใหญ่เช่นนี้เพื่อการดำเนินการอย่างง่ายเช่นการค้นหาค่าเฉลี่ย
cs95

4

ฉันมีคำถามที่คล้ายกันเพื่อแก้ปัญหาของ Udacity แทนที่จะเป็นฟังก์ชั่นในตัวฉันเขียนโค้ด:

def list_mean(n):

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

นานกว่าปกติ แต่สำหรับมือใหม่มันค่อนข้างท้าทาย


1
ดี. คำตอบอื่น ๆ ไม่ได้สังเกตถึงอันตรายของรายการที่ว่างเปล่า!
wsysuper

1
การส่งคืนFalse(เทียบเท่ากับจำนวนเต็ม0) เป็นเพียงวิธีที่เป็นไปได้ที่แย่ที่สุดในการจัดการข้อผิดพลาดนี้ ดีกว่าที่จะจับZeroDivisionErrorและยกระดับสิ่งที่ดีกว่า (อาจValueError)
kindall

@kindall เป็นอย่างไรValueErrorดีกว่าZeroDivisionError? หลังมีความเฉพาะเจาะจงมากกว่าและดูเหมือนว่าไม่จำเป็นที่จะต้องจับข้อผิดพลาดทางคณิตศาสตร์เพียงเพื่อโยนอันที่แตกต่างออกไป
MatTheWhale

เนื่องจากZeroDivisionErrorมีประโยชน์เฉพาะเมื่อคุณทราบวิธีการคำนวณ (เช่นการหารด้วยความยาวของรายการมีส่วนเกี่ยวข้อง) หากคุณไม่ทราบว่าจะไม่แจ้งให้คุณทราบถึงปัญหาที่เกิดขึ้นกับค่าที่คุณส่งไปโดยที่ข้อยกเว้นใหม่ของคุณอาจรวมถึงข้อมูลที่เฉพาะเจาะจงมากขึ้น
ใจดี

4

ในฐานะผู้เริ่มต้นฉันเพิ่งเขียนโค้ดนี้:

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)

ไชโย: IMHO sum(l)/len(l)เป็นคำตอบที่ดีที่สุด (ไม่จำเป็นต้องแปลงประเภทใน Python 3)
fralau

4

หากคุณต้องการได้รับมากกว่าค่าเฉลี่ย (aka เฉลี่ย) คุณอาจตรวจสอบสถิติ scipy

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

ในการใช้reduceสำหรับการเฉลี่ยค่าเฉลี่ยคุณจะต้องติดตามผลรวม แต่ยังรวมจำนวนองค์ประกอบทั้งหมดที่เห็น เนื่องจากนั่นไม่ใช่องค์ประกอบที่น่ารำคาญในรายการคุณจะต้องผ่านreduceการโต้แย้งเพิ่มเติมเพื่อพับลง

>>> 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
น่าสนใจ แต่นั่นไม่ใช่สิ่งที่เขาขอ
Johan Lundberg

3

ทั้งสองสามารถให้คุณใกล้เคียงกับค่าที่คล้ายกันในจำนวนเต็มหรืออย่างน้อย 10 ค่าทศนิยม แต่ถ้าคุณกำลังพิจารณาค่าลอยตัวที่ยาวนานทั้งสองอย่างอาจแตกต่างกัน วิธีการอาจแตกต่างกันไปในสิ่งที่คุณต้องการบรรลุ

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

ค่าลอยตัว

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

@Andrew Clark ถูกต้องในคำสั่งของเขา


3

สมมติว่า

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

คุณสามารถสังเกตเห็นว่าxมีขนาด 3 * 10 หากคุณต้องการไปที่meanแต่ละแถวที่คุณสามารถพิมพ์

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

อย่าลืม 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
ไม่มีประสิทธิภาพ มันจะแปลงองค์ประกอบทั้งหมดให้ลอยก่อนที่จะเพิ่มพวกเขา มันเร็วกว่าที่จะแปลงความยาว
Chris Koston

1

ค้นหาค่าเฉลี่ยในรายการโดยใช้รหัสPYTHONต่อไปนี้:

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

ลองสิ่งนี้ง่าย ๆ


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

หรือชอบโพสต์ก่อนหน้านี้

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

1.0 คือการทำให้แน่ใจว่าคุณได้รับการแบ่งจุดลอยตัว


0

เมื่อรวมคำตอบสองข้อข้างต้นเข้าด้วยกันฉันคิดว่าสิ่งต่อไปนี้ใช้งานได้กับการลดและไม่คิดว่าคุณมีLอยู่ในฟังก์ชันการลด:

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

ฉันต้องการเพิ่มวิธีอื่น

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)

จะเกิดอะไรขึ้นถ้าผู้ใช้เพิ่มหมายเลขทศนิยมลงในอาร์เรย์ ผลลัพธ์จะไม่ชัดเจนอย่างยิ่ง
Flame_Phoenix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.