ค่าเบี่ยงเบนมาตรฐานของรายการ


103

ฉันต้องการหาค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐานของ 1, 2, ... หลักของรายการ (Z) หลายตัว ตัวอย่างเช่นฉันมี

A_rank=[0.8,0.4,1.2,3.7,2.6,5.8]
B_rank=[0.1,2.8,3.7,2.6,5,3.4]
C_Rank=[1.2,3.4,0.5,0.1,2.5,6.1]
# etc (up to Z_rank )...

ตอนนี้ฉันต้องการหาค่าเฉลี่ยและมาตรฐานของ*_Rank[0]ค่าเฉลี่ยและมาตรฐานของ*_Rank[1]ฯลฯ
(เช่นค่าเฉลี่ยและค่ามาตรฐานของหลักที่ 1 จากรายการ (A..Z) _rank ทั้งหมด
ค่าเฉลี่ยและมาตรฐานของหลักที่ 2 จาก ทั้งหมด (A..Z) _ รายการอันดับ;
ค่าเฉลี่ยและมาตรฐานของหลักที่ 3 ... ; ฯลฯ )


13
สวัสดีไวรัล Stack Overflow ทำงานได้ดีที่สุดในฐานะไซต์คำถามและคำตอบ คุณถามคำถามและคนอื่น ๆ ก็ให้คำตอบ โพสต์ของคุณมีเฉพาะข้อความไม่มีคำถาม คุณมีคำถามเฉพาะเกี่ยวกับการเขียนโปรแกรมหรือไม่? พูดอีกอย่างคือตอนนี้คุณได้ลองทำอะไรแล้วและติดขัดตรงไหน?
Robᵩ

2
เหตุใดรายการเหล่านี้จึงไม่อยู่ในพจนานุกรมหรืออะไร
Waleed Khan

ขออภัยหากฉันถ่ายทอดคำถามไม่ถูกต้อง ฉันต้องการหาค่าเฉลี่ยของ A_rank [0] (0.8), B_rank [0] (0.1), C_rank [0] (1.2), ... Z_rank [0] เหมือนกันสำหรับ A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1]
Physics_for_all

คำตอบ:


150

เนื่องจาก Python 3.4 / PEP450มีอยู่statistics moduleในไลบรารีมาตรฐานซึ่งมีวิธีการstdevคำนวณค่าเบี่ยงเบนมาตรฐานของการวนซ้ำเช่นของคุณ:

>>> A_rank = [0.8, 0.4, 1.2, 3.7, 2.6, 5.8]
>>> import statistics
>>> statistics.stdev(A_rank)
2.0634114147853952

38
มันคุ้มค่าที่จะชี้ให้เห็นว่าpstddevควรใช้แทนหากรายการของคุณแสดงถึงประชากรทั้งหมด (กล่าวคือรายการไม่ใช่ตัวอย่างของประชากร) stddevคำนวณโดยใช้ความแปรปรวนของตัวอย่างและจะประเมินค่าเฉลี่ยประชากรสูงเกินไป
Alex Riley

4
มีการเรียกใช้ฟังก์ชันจริงstdevและpstdevไม่ได้ใช้stdงานstandardตามที่คาดหวัง ฉันไม่สามารถแก้ไขโพสต์ได้เนื่องจากการแก้ไขจำเป็นต้องแก้ไขอย่างน้อย 6 ตัวอักษร ...
mknaf

104

ฉันจะใส่A_Ranket al ลงในอาร์เรย์2D NumPyจากนั้นใช้numpy.mean()และnumpy.std()คำนวณค่าเฉลี่ยและค่าเบี่ยงเบนมาตรฐาน:

In [17]: import numpy

In [18]: arr = numpy.array([A_rank, B_rank, C_rank])

In [20]: numpy.mean(arr, axis=0)
Out[20]: 
array([ 0.7       ,  2.2       ,  1.8       ,  2.13333333,  3.36666667,
        5.1       ])

In [21]: numpy.std(arr, axis=0)
Out[21]: 
array([ 0.45460606,  1.29614814,  1.37355985,  1.50628314,  1.15566239,
        1.2083046 ])

2
ผลลัพธ์ของ numpy.std ไม่ถูกต้อง ให้ค่าเหล่านี้: 20,31,50,69,80 และใส่ใน Excel โดยใช้ STDEV.S (A1: A5) ผลลัพธ์คือ 25,109 ไม่ใช่ 22,45
Jim Clermonts

22
@JimClermonts มันไม่มีอะไรเกี่ยวข้องกับความถูกต้อง ไม่ว่า ddof = 0 (ค่าเริ่มต้นตีความข้อมูลเป็นประชากร) หรือ ddof = 1 (ตีความเป็นตัวอย่างเช่นการประมาณค่าความแปรปรวนที่แท้จริง) ขึ้นอยู่กับสิ่งที่คุณกำลังทำ
runDOSrun

17
เพื่อชี้แจงประเด็นของ @ runDOSrun เพิ่มเติมฟังก์ชัน Excel STDEV.P()และฟังก์ชันNumpy จะstd(ddof=0)คำนวณsd ประชากรหรือsd ตัวอย่างที่ไม่ได้แก้ไขในขณะที่ฟังก์ชัน Excel STDEV.S()และฟังก์ชัน Numpy std(ddof=1)คำนวณsd ตัวอย่าง (แก้ไข)ซึ่งเท่ากับ sqrt (N / (N-1) ) คูณด้วย sd ประชากรโดยที่ N คือจำนวนจุด ดูเพิ่มเติม: en.m.wikipedia.org/wiki/…
binaryfunt

52

นี่คือรหัส Pure-Python ที่คุณสามารถใช้คำนวณค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐาน

โค้ดทั้งหมดด้านล่างอ้างอิงจากstatisticsโมดูลใน Python 3.4+

def mean(data):
    """Return the sample arithmetic mean of data."""
    n = len(data)
    if n < 1:
        raise ValueError('mean requires at least one data point')
    return sum(data)/n # in Python 2 use sum(data)/float(n)

def _ss(data):
    """Return sum of square deviations of sequence data."""
    c = mean(data)
    ss = sum((x-c)**2 for x in data)
    return ss

def stddev(data, ddof=0):
    """Calculates the population standard deviation
    by default; specify ddof=1 to compute the sample
    standard deviation."""
    n = len(data)
    if n < 2:
        raise ValueError('variance requires at least two data points')
    ss = _ss(data)
    pvar = ss/(n-ddof)
    return pvar**0.5

หมายเหตุ: เพื่อความแม่นยำที่ดีขึ้นเมื่อรวมการลอยตัวstatisticsโมดูลจะใช้ฟังก์ชันที่กำหนดเอง_sumแทนที่จะเป็นแบบในตัวsumที่ฉันใช้แทน

ตอนนี้เรามีตัวอย่าง:

>>> mean([1, 2, 3])
2.0
>>> stddev([1, 2, 3]) # population standard deviation
0.816496580927726
>>> stddev([1, 2, 3], ddof=1) # sample standard deviation
0.1

1
มันไม่ควรpvar=ss/(n-1)?
Ranjith Ramachandra

2
@Ranjith: ถ้าคุณต้องการคำนวณความแปรปรวนตัวอย่าง (หรือตัวอย่าง SD) คุณสามารถn-1ใช้ได้ รหัสด้านบนใช้สำหรับ SD ประชากร (ดังนั้นจึงมีnระดับอิสระ)
Alex Riley

สวัสดีอเล็กซ์คุณช่วยโพสต์ฟังก์ชันสำหรับคำนวณค่าเบี่ยงเบนมาตรฐานตัวอย่างได้ไหม ฉัน จำกัด ด้วย Python2.6 ดังนั้นฉันจึงต้องถ่ายทอดฟังก์ชันนี้
Venu S

@VenuS: สวัสดีฉันได้แก้ไขstddevฟังก์ชันเพื่อให้สามารถคำนวณค่าเบี่ยงเบนมาตรฐานทั้งตัวอย่างและประชากรได้
Alex Riley

22

ใน Python 2.7.1 คุณสามารถคำนวณค่าเบี่ยงเบนมาตรฐานโดยใช้numpy.std()สำหรับ:

  • มาตรฐานประชากร : ใช้numpy.std()โดยไม่มีอาร์กิวเมนต์เพิ่มเติมนอกเหนือจากรายการข้อมูลของคุณ
  • ตัวอย่างมาตรฐาน : คุณต้องส่งค่าddof (เช่น Delta Degrees of Freedom) เป็น 1 ดังตัวอย่างต่อไปนี้:

numpy.std (<your-list>, ddof = 1 )

ตัวหารที่ใช้ในการคำนวณคือN - ddofโดยที่ N แทนจำนวนองค์ประกอบ โดยค่าเริ่มต้น ddof คือศูนย์

คำนวณมาตรฐานตัวอย่างมากกว่ามาตรฐานประชากร


10

ใน python 2.7 คุณสามารถใช้ NumPy เพื่อnumpy.std()ให้ค่าเบี่ยงเบนมาตรฐานของประชากรค่าเบี่ยงเบนมาตรฐานของประชากร

ใน Python 3.4 statistics.stdev()ส่งกลับค่าเบี่ยงเบนมาตรฐานตัวอย่าง ฟังก์ชั่นเป็นเช่นเดียวกับpstdv()numpy.std()


8

การใช้ python มีวิธีการบางอย่างดังนี้:

import statistics as st

n = int(input())
data = list(map(int, input().split()))

Approach1 - การใช้ฟังก์ชัน

stdev = st.pstdev(data)

Approach2: คำนวณความแปรปรวนและหารากที่สองของมัน

variance = st.pvariance(data)
devia = math.sqrt(variance)

แนวทางที่ 3: ใช้คณิตศาสตร์พื้นฐาน

mean = sum(data)/n
variance = sum([((x - mean) ** 2) for x in X]) / n
stddev = variance ** 0.5

print("{0:0.1f}".format(stddev))

บันทึก:

  • variance คำนวณความแปรปรวนของประชากรตัวอย่าง
  • pvariance คำนวณความแปรปรวนของประชากรทั้งหมด
  • ความแตกต่างที่คล้ายคลึงกันระหว่างstdevและpstdev

5

รหัสหลามบริสุทธิ์:

from math import sqrt

def stddev(lst):
    mean = float(sum(lst)) / len(lst)
    return sqrt(float(reduce(lambda x, y: x + y, map(lambda x: (x - mean) ** 2, lst))) / len(lst))

10
ไม่มีอะไร 'บริสุทธิ์' เกี่ยวกับ 1 ซับ Yuck. นี่คือเวอร์ชัน pythonic เพิ่มเติม:sqrt(sum((x - mean)**2 for x in lst) / len(lst))
DBrowne

3

คำตอบอื่น ๆ ครอบคลุมถึงวิธีการทำ std dev ใน python อย่างเพียงพอ แต่ไม่มีใครอธิบายวิธีการข้ามผ่านที่แปลกประหลาดที่คุณอธิบายไว้

ผมจะถือว่า AZ คือประชากรทั้งหมด หากไม่เห็นคำตอบของOmeเกี่ยวกับวิธีการอนุมานจากตัวอย่าง

ดังนั้นเพื่อให้ได้ค่าเบี่ยงเบนมาตรฐาน / ค่าเฉลี่ยของหลักแรกของทุกรายการคุณจะต้องมีสิ่งนี้:

#standard deviation
numpy.std([A_rank[0], B_rank[0], C_rank[0], ..., Z_rank[0]])

#mean
numpy.mean([A_rank[0], B_rank[0], C_rank[0], ..., Z_rank[0]])

ในการย่อโค้ดและสรุปให้เป็นตัวเลขที่ n ให้ใช้ฟังก์ชันต่อไปนี้ที่ฉันสร้างให้คุณ:

def getAllNthRanks(n):
    return [A_rank[n], B_rank[n], C_rank[n], D_rank[n], E_rank[n], F_rank[n], G_rank[n], H_rank[n], I_rank[n], J_rank[n], K_rank[n], L_rank[n], M_rank[n], N_rank[n], O_rank[n], P_rank[n], Q_rank[n], R_rank[n], S_rank[n], T_rank[n], U_rank[n], V_rank[n], W_rank[n], X_rank[n], Y_rank[n], Z_rank[n]] 

ตอนนี้คุณสามารถรับ stdd และค่าเฉลี่ยของตำแหน่งที่ n ทั้งหมดจาก AZ ดังนี้:

#standard deviation
numpy.std(getAllNthRanks(n))

#mean
numpy.mean(getAllNthRanks(n))

สำหรับใครก็ตามที่สนใจฉันสร้างฟังก์ชั่นโดยใช้ซับเดียวที่ยุ่งเหยิงนี้:str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
Samy Bencherif
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.