Odchylenie standardowe listy

104

Chcę znaleźć średnią i odchylenie standardowe pierwszej, drugiej, ... cyfry kilku list (Z). Na przykład mam

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

Teraz chcę wziąć średnią i standardową z *_Rank[0], średnią i standardową z *_Rank[1]itd.
(Tj .: średnią i standardową z pierwszej cyfry ze wszystkich list (A..Z) _rank;
średnią i standardową z drugiej cyfry z wszystkie listy (A..Z) _rank;
średnia i standardowa trzecia cyfra ...; itd.).

physics_for_all
źródło
13
Witaj, wirusowo. Przepełnienie stosu działa najlepiej jak: Pytanie -i- odpowiedzi miejscu. Zadajesz pytanie, a wszyscy inni udzielają odpowiedzi. Twój post zawiera tylko stwierdzenia, bez pytań. Masz konkretne pytanie programistyczne? Ujmując to inaczej, czego próbowałeś do tej pory i gdzie utknąłeś?
Robᵩ
2
Dlaczego tych list nie ma w słowniku?
Waleed Khan
Przepraszam, jeśli nie przekazałem poprawnie pytania. Chcę wziąć średnią A_rank [0] (0,8), B_rank [0] (0,1), C_rank [0] (1,2), ... Z_rank [0]. to samo dla A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1].
physics_for_all

Odpowiedzi:

153

Od Pythona 3.4 / PEP450 znajduje się statistics modulew standardowej biblioteki, która ma metodęstdev obliczania odchylenia standardowego iterables jak Twoja:

>>> A_rank = [0.8, 0.4, 1.2, 3.7, 2.6, 5.8]
>>> import statistics
>>> statistics.stdev(A_rank)
2.0634114147853952
Bengt
źródło
39
Warto zaznaczyć, że pstddevprawdopodobnie powinno być używane zamiast tego, jeśli lista reprezentuje całą populację (tj. Lista nie jest próbką populacji). stddevjest obliczana przy użyciu wariancji próbki i przeszacowuje średnią populacji.
Alex Riley,
4
Funkcje są faktycznie wywoływane stdevi pstdevnie są używane stdw standardsposób, jakiego można by się spodziewać. Nie mogłem edytować postu, ponieważ edycje wymagają modyfikacji co najmniej 6 znaków ...
mknaf
104

Umieściłbym A_Ranket al w tablicy 2D NumPy , a następnie użyłbymnumpy.mean() i numpy.std()obliczył średnie i odchylenia standardowe:

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 ])
NPE
źródło
2
wynik numpy.std jest nieprawidłowy. Biorąc pod uwagę te wartości: 20,31,50,69,80 i umieść w programie Excel przy użyciu ODCH.STANDARDOWE (A1: A5), wynik to 25,109, NIE 22,45.
Jim Clermonts
22
@JimClermonts To nie ma nic wspólnego z poprawnością. To, czy ddof = 0 (wartość domyślna, interpretuj dane jako populację) czy ddof = 1 (interpretuj je jako próbki, tj. Oszacuj prawdziwą wariancję), zależy od tego, co robisz.
runDOSrun
17
Aby dokładniej wyjaśnić punkt @ runDOSrun, funkcja Excel STDEV.P()i funkcja Numpy std(ddof=0)obliczają sd populacji lub nieskorygowane sd próbki , podczas gdy funkcja Excel STDEV.S()i funkcja Numpy std(ddof=1)obliczają (poprawiony) sd próbki , który jest równy sqrt (N / (N-1) ) razy populacja sd, gdzie N to liczba punktów. Zobacz więcej: en.m.wikipedia.org/wiki/…
binaryfunt
52

Oto kod w czystym Pythonie, którego możesz użyć do obliczenia średniej i odchylenia standardowego.

Cały poniższy kod jest oparty na statisticsmodule w Pythonie 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

Uwaga: aby zwiększyć dokładność sumowania wartości zmiennoprzecinkowych, statisticsmoduł używa funkcji niestandardowej _sumzamiast funkcji wbudowanej, sumktórej użyłem zamiast niej.

Teraz mamy na przykład:

>>> 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
Alex Riley
źródło
1
Nie powinno pvar=ss/(n-1)?
Ranjith Ramachandra
2
@Ranjith: jeśli chcesz obliczyć wariancję próbki (lub SD próbki), możesz użyć n-1. Powyższy kod dotyczy populacji SD (więc istnieją nstopnie swobody).
Alex Riley
Witaj Alex, czy mógłbyś zamieścić funkcję obliczania odchylenia standardowego próbki? Jestem ograniczony w Pythonie2.6, więc muszę polegać na tej funkcji.
Venu S
@VenuS: Witam, zmodyfikowałem stddevfunkcję, aby mogła obliczyć odchylenia standardowe próbki i populacji.
Alex Riley
22

W Pythonie 2.7.1 możesz obliczyć odchylenie standardowe za pomocą numpy.std():

  • Std populacji : po prostu używaj numpy.std()bez dodatkowych argumentów oprócz listy danych.
  • Przykładowe std : Musisz przekazać ddof (tj. Delta Degrees of Freedom) ustawioną na 1, jak w poniższym przykładzie:

numpy.std (<twoja-lista>, ddof = 1 )

Dzielnik używany w obliczeniach to N - ddof , gdzie N reprezentuje liczbę elementów. Domyślnie ddof ma wartość zero.

Oblicza standardową próbkę zamiast standardowej populacji.

Ome
źródło
8

Używając Pythona, oto kilka metod:

import statistics as st

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

Approach1 - za pomocą funkcji

stdev = st.pstdev(data)

Podejście 2: oblicz wariancję i weź z niej pierwiastek kwadratowy

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

Podejście 3: używanie podstawowej matematyki

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

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

Uwaga:

  • variance oblicza wariancję populacji próbki
  • pvariance oblicza wariancję całej populacji
  • podobne różnice między stdevipstdev
pankaj
źródło
5

czysty kod Pythona:

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))
Elad Yehezkel
źródło
10
Nie ma nic „czystego” w tym 1-liniowym. Fuj. Oto bardziej pythonowa wersja:sqrt(sum((x - mean)**2 for x in lst) / len(lst))
DBrowne
3

Inne odpowiedzi obejmują wystarczająco, jak zrobić std dev w Pythonie, ale nikt nie wyjaśnia, jak wykonać dziwaczne przejście, które opisałeś.

Zakładam, że AZ to cała populacja. Jeśli nie, zobacz odpowiedź Ome na temat wnioskowania na podstawie próbki.

Aby uzyskać odchylenie standardowe / średnią z pierwszej cyfry na każdej liście, potrzebowałbyś czegoś takiego:

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

Aby skrócić kod i uogólnić go na dowolną n-tą cyfrę, użyj następującej funkcji, którą dla ciebie wygenerowałem:

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

Teraz możesz po prostu pobrać stdd i średnią wszystkich n-tych miejsc od AZ w ten sposób:

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

#mean
numpy.mean(getAllNthRanks(n))
Samy Bencherif
źródło
Dla każdego zainteresowanego wygenerowałem funkcję za pomocą tego niechlujnego jednowierszowego:str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
Samy Bencherif