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.