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


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

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

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

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.



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

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

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

Para cualquiera que str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
esté
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.