Como faço para calcular o desvio padrão do python sem usar numpy?

0

Pergunta

Eu estou tentando calcular o desvio padrão do python, sem o uso de numpy ou qualquer biblioteca externa, exceto para math. Eu quero ficar melhor na escrita de algoritmos e só estou fazendo isso como um pouco de "trabalho de casa" como eu melhorar a minha python habilidades. Meu objetivo é traduzir esta fórmula em python, mas não estou conseguindo o resultado correto.

Eu estou usando uma matriz de velocidades onde speeds = [86,87,88,86,87,85,86]

Quando eu executo:

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

Eu recebo: 0.903507902905. Mas eu não quero depender de numpy. Então...

Minha implementação é da seguinte maneira:

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)

Agora, quando eu executar:

std_dev = get_std_dev(speeds)
print(std_dev)

Eu recebo: [0] mas eu estou esperando 0.903507902905

O que estou ausente aqui?

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

Melhor resposta

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

Quando eu executo que eu tenho 1.0.
bkleeman

Reinicie o python kernel. Algo que tenha feito ferrou com uma das funções internas.
CJR

Ah, não importa, você está usando python2.7, não você. Adicionar from __future__ import division - o padrão de divisão / não é verdade divisão até o python 3.0, a menos que você importar do futuro.
CJR

sim, eu estou usando 2.7. A solução mais o futuro da divisão de importação está trabalhando para mim agora. Muito obrigado pela ajuda!
bkleeman

É hora de se mover para py3, companheiro.
CJR

Eu sou muito novo para python e que eu ainda não descobri a rima ou razão para quando a minha máquina é executado py2 vs py3, para ser honesto. Eu vou ter isso resolvido fora.
bkleeman

Muitas distribuições de linux navio com py2.7 e py3 - você provavelmente tem python3 (mas o binário é python3 em vez de apenas python). Você também pode considerar o uso de algo como anaconda para configurar ambientes. py2.7 é bem passado fim-de-vida.
CJR
1

O problema no seu código é o reaproveitamento do array e retornar no meio do ciclo

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

Agora vamos olhar para o algoritmo que você está usando. Observe que há duas desvio padrão fórmulas que são comumente usados. Existem vários argumentos a qual é correta.

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

ou

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

Para grandes valores de n, a primeira fórmula é utilizada desde a -1 é insignificante. A primeira fórmula pode ser reduzido para

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

Então, como você fazer isso em 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

alguns problemas no código, um deles é o valor de retorno dentro da instrução for. você pode tentar isso

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

Isso. Você precisa se livrar de return dentro de loops.

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

Se você não quiser usar numpy o seu ok, dê uma chance para statistics pacote python

import statistics

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

ou se você ainda estiver disposto a usar uma solução personalizada, em seguida, eu recomendo que você use o seguinte maneira utilizando a lista de compreensão em vez de seu complexo de buggy abordagem

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

Em outros idiomas

Esta página está em outros idiomas

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