Độ lệch chuẩn của danh sách


103

Tôi muốn tìm trung bình và độ lệch chuẩn của các chữ số 1, 2, ... của một số danh sách (Z). Ví dụ, tôi có

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

Bây giờ tôi muốn lấy giá trị trung bình và điểm trung bình của *_Rank[0], giá trị trung bình và điểm thứ nhất *_Rank[1], v.v.
(nghĩa là: giá trị trung bình và điểm số 1 từ tất cả danh sách _rank (A..Z);
giá trị trung bình và điểm số thứ 2 từ tất cả danh sách (A..Z) _rank;
giá trị trung bình và std của chữ số thứ 3 ...; v.v.).


13
Xin chào, virus. Stack Overflow hoạt động tốt nhất như một trang web câu hỏicâu trả lời . Bạn đặt một câu hỏi và mọi người khác cung cấp câu trả lời. Bài đăng của bạn chỉ chứa các tuyên bố, không có câu hỏi. Bạn có một câu hỏi lập trình cụ thể? Nói cách khác, bạn đã cố gắng những gì cho đến nay, và bạn đang mắc kẹt ở đâu?
Robᵩ

2
Tại sao những danh sách này không có trong từ điển hay gì đó?
Waleed Khan

Xin lỗi nếu tôi không truyền đạt câu hỏi đúng cách. Tôi muốn lấy giá trị trung bình của A_rank [0] (0.8), B_rank [0] (0.1), C_rank [0] (1.2), ... Z_rank [0]. tương tự cho A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1].
Physics_for_all

Câu trả lời:


150

Vì Python 3.4 / PEP450 có một statistics moduletrong thư viện chuẩn, có một phương phápstdev để tính toán độ lệch chuẩn của các tệp lặp như của bạn:

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

38
Cần chỉ ra rằng pstddevcó lẽ nên được sử dụng thay thế nếu danh sách của bạn đại diện cho toàn bộ tập hợp (tức là danh sách không phải là một mẫu của một tập hợp). stddevđược tính toán bằng cách sử dụng phương sai mẫu và sẽ ước tính quá mức trung bình tổng thể.
Alex Riley

4
Các chức năng đang thực sự gọi stdevpstdev, không sử dụng stdcho standardnhư người ta mong đợi. Tôi không thể chỉnh sửa bài như chỉnh sửa cần phải sửa đổi ít nhất 6 ký tự ...
mknaf

104

Tôi sẽ đặt A_Ranket al vào một mảng 2D NumPy , sau đó sử dụng numpy.mean()numpy.std()tính toán các phương tiện và độ lệch chuẩn:

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
kết quả của numpy.std không đúng. Cho các giá trị sau: 20,31,50,69,80 và đặt trong Excel bằng STDEV.S (A1: A5) kết quả là 25,109 KHÔNG phải 22,45.
Jim Clermonts

22
@JimClermonts Nó không liên quan gì đến tính đúng đắn. Việc ddof = 0 (mặc định, giải thích dữ liệu là tổng thể) hay ddof = 1 (diễn giải nó là các mẫu, tức là ước tính phương sai thực sự) phụ thuộc vào những gì bạn đang làm.
runDOSrun

17
Để làm rõ thêm @ điểm runDOSrun của, hàm Excel STDEV.P()và các chức năng NumPy std(ddof=0)tính toán dân số sd, hoặc mẫu uncorrected sd, trong khi chức năng Excel STDEV.S()và NumPy chức năng std(ddof=1)tính toán (điều chỉnh) mẫu sd, bằng sqrt (N / (N-1) ) nhân với sd dân số, trong đó N là số điểm. Xem thêm: en.m.wikipedia.org/wiki/…
binaryfunt

52

Đây là một số mã Python thuần túy mà bạn có thể sử dụng để tính giá trị trung bình và độ lệch chuẩn.

Tất cả mã bên dưới đều dựa trên statisticsmô-đun trong 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

Lưu ý: để cải thiện độ chính xác khi tính tổng số float, statisticsmô-đun sử dụng một chức năng tùy chỉnh _sumthay vì tích hợp sẵn summà tôi đã sử dụng ở vị trí của nó.

Bây giờ chúng ta có ví dụ:

>>> 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
Có nên không pvar=ss/(n-1)?
Ranjith Ramachandra

2
@Ranjith: nếu bạn muốn tính phương sai mẫu (hoặc SD mẫu), bạn có thể sử dụng n-1. Đoạn mã trên dành cho dân số SD (vì vậy có nbậc tự do).
Alex Riley

Xin chào Alex, Bạn có thể vui lòng đăng chức năng tính toán độ lệch chuẩn mẫu không? Tôi bị giới hạn với Python2.6, vì vậy tôi phải chuyển tiếp trên chức năng này.
Venu S

@VenuS: Xin chào, tôi đã chỉnh sửa stddevhàm để nó có thể tính toán cả độ lệch chuẩn mẫu và tổng thể.
Alex Riley

22

Trong Python 2.7.1, bạn có thể tính toán độ lệch chuẩn bằng cách sử dụng numpy.std()cho:

  • Dân số std : Chỉ sử dụng numpy.std()mà không có đối số bổ sung nào ngoài danh sách dữ liệu của bạn.
  • Mẫu std : Bạn cần chuyển ddof (tức là Delta Degrees of Freedom) được đặt thành 1, như trong ví dụ sau:

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

Ước số được sử dụng trong tính toán là N - ddof , trong đó N đại diện cho số phần tử. Theo mặc định, ddof là 0.

Nó tính toán std mẫu hơn là std dân số.



8

Sử dụng python, đây là một số phương pháp:

import statistics as st

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

Phương pháp tiếp cận1 - sử dụng một hàm

stdev = st.pstdev(data)

Phương pháp tiếp cận 2: tính toán phương sai và lấy căn bậc hai của nó

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

Phương pháp 3: sử dụng toán học cơ bản

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

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

Ghi chú:

  • variance tính toán phương sai của tổng thể mẫu
  • pvariance tính toán phương sai của toàn bộ tập hợp
  • sự khác biệt tương tự giữa stdevpstdev

5

mã trăn nguyên chất:

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
Không có gì 'tinh khiết' về 1 lớp lót đó. Kinh quá. Dưới đây là phiên bản pythonic hơn:sqrt(sum((x - mean)**2 for x in lst) / len(lst))
DBrowne

3

Các câu trả lời khác bao gồm cách thực hiện std dev trong python đầy đủ, nhưng không ai giải thích cách thực hiện chuyển động kỳ lạ mà bạn đã mô tả.

Tôi sẽ giả định AZ là toàn bộ dân số. Nếu không xem câu trả lời của Ome về cách suy luận từ một mẫu.

Vì vậy, để có được độ lệch chuẩn / giá trị trung bình của chữ số đầu tiên của mọi danh sách, bạn sẽ cần một cái gì đó như sau:

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

Để rút ngắn mã và tổng quát hóa mã này thành bất kỳ chữ số thứ n nào, hãy sử dụng hàm sau mà tôi đã tạo cho bạ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]] 

Bây giờ bạn có thể chỉ cần lấy stdd và trung bình của tất cả các địa điểm thứ n từ AZ như sau:

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

#mean
numpy.mean(getAllNthRanks(n))

Đối với bất kỳ ai quan tâm, tôi đã tạo hàm bằng cách sử dụng một lớp lót lộn xộn này:str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
Samy Bencherif
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.