Jak obliczyć odchylenie standardowe w pythonie bez użycia numpy?

0

Pytanie

Próbuję obliczyć odchylenie standardowe w pythonie bez użycia numpy lub jakiejkolwiek zewnętrznej biblioteki, za wyjątkiem math. Chcę stać się lepszy w pisaniu algorytmów i po prostu robię to jako "zadania domowego", doskonaląc swoje umiejętności pracy w pythonie. Mój cel-przenieść tę formułę w pythonie, ale nie otrzymuję prawidłowego wyniku.

Używam wielu prędkości, gdzie speeds = [86,87,88,86,87,85,86]

Kiedy biegnę:

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

Otrzymuję: 0,903507902905. Ale ja nie chcę polegać na глупышку. Tak...

Moja implementacja jest w następujący sposób:

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)

Teraz, gdy używam:

std_dev = get_std_dev(speeds)
print(std_dev)

Otrzymuję: [0] ale spodziewam się 0,903507902905

Co ja tutaj nie dostrzegam?

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

Najlepsza odpowiedź

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

Kiedy biegnę, mam 1.0.
bkleeman

Uruchom ponownie rdzeń python. Coś, co zrobiłeś, zepsuło jedną z wbudowanych funkcji.
CJR

O, nie bierz do głowy, że używasz python2.7, prawda? Dodać from __future__ import division - standardowa jednostka / to zły podział do pythona 3.0, jeśli nie zostaną zaimportowane z przyszłości.
CJR

tak, używam 2.7. Swoją decyzję plus import przyszłości jednostki teraz działa na mnie. Bardzo wam dziękuję za pomoc!
bkleeman

Nadszedł czas, aby przejść do py3, kolego.
CJR

Jestem dość początkujący w pythonie, i, szczerze mówiąc, tego jeszcze nie wiem wierszyk lub przyczynę tego, gdy moja maszyna uruchamia py2 przeciwko py3. Będę musiał się tym zająć.
bkleeman

Wiele dystrybucji Linuksa są dostarczane z py2.7 i py3 - u ciebie pewnie jest python3 (ale plik binarny python3 zamiast po prostu python). Można również rozważyć użycie czegoś takiego jak anakondy dla ustawienia środowiska. py2.7 dawno upłynął okres eksploatacji.
CJR
1

Problem w kodzie polega na ponownym wykorzystaniu tablicy i zwrot w środku cyklu

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

Teraz rozważmy algorytm, który używasz. Należy pamiętać, że zazwyczaj są używane dwie formuły odchylenie std. Istnieją różne argumenty odnośnie tego, który z nich jest prawidłowy.

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

lub

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

Dla dużych wartości n jest używany pierwsza formuła, tak jak wartość -1 nieznacznie. Pierwsza formuła może być zredukowana do

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

Więc jak byś zrobił to w pythonie?

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

niektóre problemy w kodzie, jedna z nich-wartość zwracana wewnątrz instrukcji for. możesz spróbować

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

Ten. Musisz pozbyć się return wewnątrz pętli.

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

Jeśli nie chcesz korzystać numpy wszystko w porządku, spróbuj statistics pakiet python

import statistics

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

lub, jeśli nadal są gotowe do użycia indywidualne rozwiązanie, polecam użyć następującej metody, za pomocą zrozumienie listy zamiast swojego skomplikowanego podejścia z błędami

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

W innych językach

Ta strona jest w innych językach

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