¿Cómo puedo calcular la desviación estándar de python sin el uso de numpy?

0

Pregunta

Estoy tratando de calcular la desviación estándar de python sin el uso de numpy o de ninguna librería externa, excepto para math. Quiero ser mejor en la escritura de algoritmos y sólo estoy haciendo esto como un poco de "deberes" como puedo mejorar mi python habilidades. Mi objetivo es traducir esta fórmula en python, pero no estoy recibiendo el resultado correcto.

Estoy usando una matriz de velocidades donde speeds = [86,87,88,86,87,85,86]

Cuando ejecuto:

std_dev = numpy.std(speeds)
print(std_dev)

Puedo obtener: 0.903507902905. Pero no quiero depender de numpy. Así que...

Mi aplicación es la siguiente:

import math

speeds = [86,87,88,86,87,85,86]

def get_mean(array):
    sum = 0
    for i in array:
        sum = sum + i
    mean = sum/len(array)
    return mean

def get_std_dev(array):
    # get mu
    mean = get_mean(array)
    # (x[i] - mu)**2
    for i in array:
        array = (i - mean) ** 2
        return array
    sum_sqr_diff = 0
    # get sigma
    for i in array:
        sum_sqr_diff = sum_sqr_diff + i
        return sum_sqr_diff
    # get mean of squared differences
    variance = 1/len(array)
    mean_sqr_diff = (variance * sum_sqr_diff)
    
    std_dev = math.sqrt(mean_sqr_diff)
    return std_dev

std_dev = get_std_dev(speeds)
print(std_dev)

Ahora cuando ejecuto:

std_dev = get_std_dev(speeds)
print(std_dev)

Obtengo: [0] pero estoy esperando 0.903507902905

Lo que me estoy perdiendo aquí?

algorithm mean python standard-deviation
2021-11-23 20:46:59
5

Mejor respuesta

1
speeds = [86,87,88,86,87,85,86]

# Calculate the mean of the values in your list
mean_speeds = sum(speeds) / len(speeds)

# Calculate the variance of the values in your list
# This is 1/N * sum((x - mean(X))^2)
var_speeds = sum((x - mean_speeds) ** 2 for x in speeds) / len(speeds)

# Take the square root of variance to get standard deviation
sd_speeds = var_speeds ** 0.5

>>> sd_speeds
0.9035079029052513
2021-11-23 21:10:27

Cuando me encuentro con que tengo 1.0.
bkleeman

Reinicie el núcleo de python. Algo que ha hecho ha jodido con una de las funciones integradas.
CJR

Oh, no importa, estás usando python2.7, no usted. Agregar from __future__ import division - el estándar de la división de / no es cierto división hasta python 3.0, a menos que usted importación de futuro.
CJR

sí, yo estoy usando 2.7. Su solución, además de la futura división de importación está trabajando para mí ahora. Muchas gracias por la ayuda!
bkleeman

Es tiempo de pasar a py3, compañero.
CJR

Soy bastante nuevo en python y todavía no he averiguado la rima o razón cuando mi máquina funciona py2 vs py3, para ser honesto. Voy a tener que conseguir que se solucione.
bkleeman

Una gran cantidad de distribuciones de linux barco con py2.7 y py3 - probablemente tiene python3 (pero el binario es python3 en lugar de sólo python). También puede considerar el uso de algo como anaconda para configurar entornos. py2.7 es bien pasado el final de la vida.
CJR
1

El problema en tu código es la reutilización de la matriz y la vuelta en la mitad del bucle

def get_std_dev(array):
    # get mu
    mean = get_mean(array)       <-- this is 86.4
    # (x[i] - mu)**2
    for i in array:
        array = (i - mean) ** 2  <-- this is almost 0
        return array             <-- this is the value returned

Ahora veamos el algoritmo que se está utilizando. Tenga en cuenta que hay dos ets de la desviación de las fórmulas que se utilizan comúnmente. Hay varios argumentos en cuanto a cuál es la correcta.

sqrt(sum((x - mean)^2) / n)

o

sqrt(sum((x - mean)^2) / (n -1))

Para grandes valores de n, la primera fórmula se utiliza desde el -1 es insignificante. La primera fórmula puede ser reducido a

sqrt(sum(x^2) /n - mean^2)

Entonces, ¿cómo se puede hacer esto en python?

def std_dev1(array):
   n = len(array)
   mean = sum(array) / n
   sumsq = sum(v * v for v in array)
   return (sumsq / n - mean * mean) ** 0.5
2021-11-24 06:21:59
-1

algunos problemas en el código, uno de ellos es el valor de retorno dentro de la instrucción for. usted puede probar esto

def get_mean(array):
    return sum(array) / len(array)


def get_std_dev(array):
    n = len(array)
    mean = get_mean(array)
    squares_arr = []
    for item in array:
        squares_arr.append((item - mean) ** 2)
    return math.sqrt(sum(squares_arr) / n)
2021-11-23 22:06:23
-2

Este. Usted necesita para deshacerse de return dentro de bucles.

def get_std_dev(array):
    # get mu
    mean = get_mean(array)
    sum_sqr_diff = 0
    # get sigma
    for i in array:
        sum_sqr_diff = sum_sqr_diff + (i - mean)**2
    # get mean of squared differences
    variance = 1/len(array)
    mean_sqr_diff = (variance * sum_sqr_diff)
    
    std_dev = math.sqrt(mean_sqr_diff)
    return std_dev
2021-11-23 20:59:12
-2

Si usted no desea utilizar numpy está bien darle una oportunidad a statistics paquete de python

import statistics

st_dev = statistics.pstdev(speeds)
print(st_dev)

o si usted todavía está dispuesto a utilizar una solución personalizada, a continuación, te recomiendo usar la siguiente manera utilizando la lista de comprensión en lugar de su complejo buggy enfoque

import math

mean = sum(speeds) / len(speeds)
var = sum((l-mean)**2 for l in speeds) / len(speeds)
st_dev = math.sqrt(var)
print(st_dev)
2021-11-23 20:58:42

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................