Desviación estándar de una lista

103

Quiero encontrar la desviación estándar y media del primer, segundo, ... dígitos de varias listas (Z). Por ejemplo, tengo

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

Ahora quiero tomar la media y estándar de *_Rank[0], la media y estándar de *_Rank[1], etc.
(es decir: media y estándar del primer dígito de todas las listas (A..Z) _rank;
la media y estándar del segundo dígito de todas las listas (A..Z) _rank;
la media y estándar del tercer dígito ...; etc.).

física_para_todos
fuente
13
Hola, viral. Stack Overflow funciona mejor como un sitio de preguntas y respuestas . Haces una pregunta y todos los demás dan respuestas. Tu publicación contiene solo declaraciones, no preguntas. ¿Tiene una pregunta de programación específica? Para decirlo de otra manera, ¿qué ha intentado hasta ahora y dónde está atrapado?
Robᵩ
2
¿Por qué estas listas no están en un diccionario o algo así?
Waleed Khan
Lo siento si no transmití la pregunta correctamente. Quiero tomar la media de A_rank [0] (0.8), B_rank [0] (0.1), C_rank [0] (1.2), ... Z_rank [0]. lo mismo para A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1].
physics_for_all

Respuestas:

150

Desde Python 3.4 / PEP450 hay un statistics moduleen la biblioteca estándar, que tiene un métodostdev para calcular la desviación estándar de iterables como el suyo:

>>> A_rank = [0.8, 0.4, 1.2, 3.7, 2.6, 5.8]
>>> import statistics
>>> statistics.stdev(A_rank)
2.0634114147853952
Bengt
fuente
38
Vale la pena señalar que pstddevprobablemente debería usarse en su lugar si su lista representa a toda la población (es decir, la lista no es una muestra de una población). stddevse calcula utilizando la varianza de la muestra y sobrestimará la media de la población.
Alex Riley
4
En realidad, las funciones se llaman stdevy pstdevno se usan stdpara standardcomo cabría esperar. No pude editar la publicación ya que las ediciones deben modificar al menos 6 caracteres ...
mknaf
104

Pondría A_Ranket al en una matriz 2D NumPy , y luego usaría numpy.mean()y numpy.std()para calcular las medias y las desviaciones estándar:

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
fuente
2
el resultado de numpy.std no es correcto. Dados estos valores: 20,31,50,69,80 y puesto en Excel usando STDEV. S (A1: A5) el resultado es 25,109 NO 22,45.
Jim Clermonts
22
@JimClermonts No tiene nada que ver con la corrección. Si ddof = 0 (predeterminado, interpretar los datos como población) o ddof = 1 (interpretarlos como muestras, es decir, estimar la varianza verdadera) depende de lo que esté haciendo.
runDOSrun
17
Para aclarar aún más el punto de @ runDOSrun, la función de Excel STDEV.P()y la función Numpy std(ddof=0)calculan la sd de la población , o la sd de la muestra sin corregir , mientras que la función de Excel STDEV.S()y la función Numpy std(ddof=1)calculan la sd de la muestra (corregida) , que es igual a sqrt (N / (N-1) ) multiplicado por la población sd, donde N es el número de puntos. Ver más: en.m.wikipedia.org/wiki/…
binaryfunt
52

Aquí hay un código de Python puro que puede usar para calcular la desviación estándar y media.

Todo el código siguiente se basa en el statisticsmódulo en 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: para mejorar la precisión al sumar flotantes, el statisticsmódulo usa una función personalizada en _sumlugar de la incorporada sumque he usado en su lugar.

Ahora tenemos por ejemplo:

>>> 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
fuente
1
¿No debería ser así pvar=ss/(n-1)?
Ranjith Ramachandra
2
@Ranjith: si desea calcular la varianza de la muestra (o la SD de la muestra) puede usar n-1. El código anterior es para la población SD (por lo que hay ngrados de libertad).
Alex Riley
Hola Alex, ¿podrías publicar una función para calcular la desviación estándar de la muestra? Estoy limitado con Python2.6, así que tengo que confiar en esta función.
Venu S
@VenuS: Hola, he editado la stddevfunción para que pueda calcular las desviaciones estándar de la muestra y la población.
Alex Riley
22

En Python 2.7.1, puede calcular la desviación estándar usando numpy.std()para:

  • Estándar de población : utilícelo numpy.std()sin argumentos adicionales además de su lista de datos.
  • Ejemplo de estándar : debe pasar ddof (es decir, Delta Degrees of Freedom) establecido en 1, como en el siguiente ejemplo:

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

El divisor utilizado en los cálculos es N - ddof , donde N representa el número de elementos. Por defecto, ddof es cero.

Calcula la estándar de muestra en lugar de la estándar de población.

Ome
fuente
8

Usando Python, aquí hay algunos métodos:

import statistics as st

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

Enfoque1: uso de una función

stdev = st.pstdev(data)

Método 2: calcular la varianza y sacar su raíz cuadrada

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

Enfoque 3: usar matemáticas básicas

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 calcula la varianza de la población de muestra
  • pvariance calcula la varianza de toda la población
  • diferencias similares entre stdevypstdev
pankaj
fuente
5

código 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))
Elad Yehezkel
fuente
10
No hay nada "puro" en ese 1-liner. ¡Qué asco! Aquí hay más versión pitónica:sqrt(sum((x - mean)**2 for x in lst) / len(lst))
DBrowne
3

Las otras respuestas cubren cómo hacer std dev en python lo suficiente, pero nadie explica cómo hacer el extraño recorrido que ha descrito.

Voy a asumir que AZ es toda la población. Si no, vea la respuesta de Ome sobre cómo hacer una inferencia a partir de una muestra.

Entonces, para obtener la desviación estándar / media del primer dígito de cada lista, necesitaría algo como esto:

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

Para acortar el código y generalizarlo a cualquier enésimo dígito, use la siguiente función que generé para usted:

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

Ahora puede simplemente obtener el stdd y la media de todos los enésimos lugares de AZ de esta manera:

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

#mean
numpy.mean(getAllNthRanks(n))
Samy Bencherif
fuente
Para cualquiera que str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
esté