Deviazione standard di una lista


103

Voglio trovare la media e la deviazione standard delle cifre 1a, 2a, ... di diversi elenchi (Z). Ad esempio, ho

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

Ora voglio prendere la media e lo std di *_Rank[0], la media e lo std di *_Rank[1], ecc.
(Cioè: media e std della prima cifra da tutti gli elenchi (A..Z) _rank;
la media e std della seconda cifra da tutte le liste (A..Z) _rank;
la media e lo std della 3a cifra ...; ecc.).


13
Ciao, virale. Stack Overflow funziona meglio come una domanda -e- risposta sito. Fai una domanda e tutti gli altri forniscono le risposte. Il tuo post contiene solo dichiarazioni, nessuna domanda. Hai una domanda specifica sulla programmazione? Per dirla in un altro modo, cosa hai provato finora e dove sei bloccato?
Robᵩ

2
Perché questi elenchi non sono in un dizionario o qualcosa del genere?
Waleed Khan

Scusa se non ho trasmesso correttamente la domanda. Voglio prendere la media di A_rank [0] (0.8), B_rank [0] (0.1), C_rank [0] (1.2), ... Z_rank [0]. stesso per A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1].
physics_for_all

Risposte:


150

A partire da Python 3.4 / PEP450 c'è statistics modulenella libreria standard, che ha un metodostdev per calcolare la deviazione standard di iterabili come il tuo:

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

38
Vale la pena sottolineare che pstddevprobabilmente dovrebbe essere usato al suo posto se l'elenco rappresenta l'intera popolazione (cioè l'elenco non è un campione di una popolazione). stddevviene calcolato utilizzando la varianza del campione e sovrastimerà la media della popolazione.
Alex Riley

4
Le funzioni sono in realtà chiamati stdeve pstdev, non si utilizza stdper standardcome ci si aspetterebbe. Non ho potuto modificare il post perché le modifiche devono modificare almeno 6 caratteri ...
mknaf

104

Vorrei inserire A_Ranket al in un array NumPy 2D , quindi utilizzare numpy.mean()e numpy.std()per calcolare le medie e le deviazioni standard:

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
il risultato di numpy.std non è corretto. Dati questi valori: 20,31,50,69,80 e inserire in Excel utilizzando DEV.ST.ST (A1: A5) il risultato è 25,109 NON 22,45.
Jim Clermonts

22
@JimClermonts Non ha niente a che fare con la correttezza. Se ddof = 0 (predefinito, interpreta i dati come popolazione) o ddof = 1 (interpretalo come campioni, ovvero stima la varianza reale) dipende da ciò che stai facendo.
runDOS Corri il

17
Per chiarire ulteriormente il punto di @ runDOSrun, la funzione Excel STDEV.P()e la funzione Numpy std(ddof=0)calcolano la sd della popolazione , o sd del campione non corretto , mentre la funzione Excel STDEV.S()e la funzione Numpy std(ddof=1)calcolano la sd del campione (corretta) , che è uguale a sqrt (N / (N-1) ) volte la popolazione sd, dove N è il numero di punti. Vedi di più: en.m.wikipedia.org/wiki/…
binaryfunt

52

Ecco un po 'di codice Python puro che puoi usare per calcolare la media e la deviazione standard.

Tutto il codice di seguito è basato sul statisticsmodulo in 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

Nota: per una maggiore precisione durante la somma dei float, il statisticsmodulo utilizza una funzione personalizzata _sumanziché quella incorporata sumche ho usato al suo posto.

Ora abbiamo ad esempio:

>>> 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
Non dovrebbe essere pvar=ss/(n-1)?
Ranjith Ramachandra

2
@Ranjith: se vuoi calcolare la varianza del campione (o SD campione) puoi usare n-1. Il codice sopra è per la popolazione SD (quindi ci sono ngradi di libertà).
Alex Riley

Ciao Alex, potresti pubblicare una funzione per il calcolo della deviazione standard del campione? Sono limitato con Python2.6, quindi devo affidarmi a questa funzione.
Venu S

@VenuS: Ciao, ho modificato la stddevfunzione in modo che possa calcolare le deviazioni standard sia del campione che della popolazione.
Alex Riley

22

In Python 2.7.1, puoi calcolare la deviazione standard usando numpy.std()per:

  • Popolazione std : basta usare numpy.std()senza argomenti aggiuntivi oltre all'elenco dei dati.
  • Standard di esempio : è necessario passare ddof (ovvero Delta Degrees of Freedom) impostato su 1, come nell'esempio seguente:

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

Il divisore utilizzato nei calcoli è N - ddof , dove N rappresenta il numero di elementi. Per impostazione predefinita ddof è zero.

Calcola lo standard del campione anziché lo standard della popolazione.



8

Usando Python, ecco alcuni metodi:

import statistics as st

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

Approach1: utilizzo di una funzione

stdev = st.pstdev(data)

Approccio2: calcola la varianza e prendi la radice quadrata di essa

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

Approccio 3: utilizzo della matematica di base

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

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

Nota:

  • variance calcola la varianza della popolazione campione
  • pvariance calcola la varianza dell'intera popolazione
  • differenze simili tra stdevepstdev

5

codice Python puro:

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
Non c'è niente di "puro" in quella 1 riga. Che schifo. Ecco una versione più pitonica:sqrt(sum((x - mean)**2 for x in lst) / len(lst))
DBrowne

3

Le altre risposte spiegano come eseguire sufficientemente lo std dev in Python, ma nessuno spiega come eseguire il bizzarro attraversamento che hai descritto.

Presumo che l'AZ sia l'intera popolazione. In caso contrario, vedere la risposta di Ome su come dedurre da un campione.

Quindi, per ottenere la deviazione standard / media della prima cifra di ogni elenco, avresti bisogno di qualcosa del genere:

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

Per accorciare il codice e generalizzarlo a qualsiasi ennesima cifra usa la seguente funzione che ho generato per te:

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

Ora puoi semplicemente ottenere lo stdd e la media di tutti gli ennesimi posti dalla A alla Z in questo modo:

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

#mean
numpy.mean(getAllNthRanks(n))

Per chiunque fosse interessato, ho generato la funzione usando questo disordinato one-liner:str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
Samy Bencherif
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.