Jak mám vypočítat směrodatnou odchylku v pythonu bez použití numpy?

0

Otázka

Snažím se vypočítat směrodatnou odchylku v pythonu bez použití numpy nebo nějaké externí knihovny výjimkou math. Chci se dostat lepší na psaní algoritmů a jsem jen dělat to jako "domácí úkol", jak jsem zlepšit své python dovednosti. Mým cílem je přeložit tento vzorec do pythonu, ale nejsem dostat správný výsledek.

Jsem pomocí pole rychlostí, kde speeds = [86,87,88,86,87,85,86]

Když jsem spustit:

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

Chápu: 0.903507902905. Ale nechci se spoléhat na numpy. Takže...

V mé implementaci je následující:

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)

Teď, když jsem spustit:

std_dev = get_std_dev(speeds)
print(std_dev)

Jsem se: [0] ale já jsem očekával 0.903507902905

Co mi tu chybí?

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

Nejlepší odpověď

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

Když jsem běžel, že jsem si 1.0.
bkleeman

Restartujte python jádra. Něco, co jste udělal, jsem v háji s jedním z vestavěných funkcí.
CJR

Oh, to nevadí, jsi pomocí python2.7, nejsi. Přidat from __future__ import division - standardní oddělení / není pravda, dělení, dokud python 3.0, pokud importujete z budoucnosti.
CJR

ano používám 2.7. Vaše řešení plus budoucnosti divize import funguje pro mě teď. Děkuji moc za pomoc!
bkleeman

Je čas přejít na py3, kámo.
CJR

Jsem docela nový python a ještě jsem zjistil, rým nebo důvod, když můj stroj běží py2 vs py3 být upřímný. Budu muset nechat spravit.
bkleeman

Hodně linuxových distribucích loď s py2.7 a py3 - pravděpodobně jste python3 (ale je binární python3 místo toho, aby jen python). Můžete také zvážit použití něco jako anakonda nastavit prostředí. py2.7 je dobře, že v minulosti end-of-life.
CJR
1

Problém v kódu je znovu použít z pole a vrátit se ve středu smyčky

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

Nyní se podíváme na algoritmus, který používáte. Všimněte si, že tam jsou dvě std. odchylka vzorce, které jsou běžně používány. Existují různé argumenty, které z nich je správné.

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

nebo

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

Pro velké hodnoty n, první vzorec se používá od -1 je zanedbatelný. První vzorec může být snížena na

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

Tak jak bys to udělal v pythonu?

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

některé problémy v kódu, jedna z nich je návratová hodnota uvnitř pro prohlášení. můžete zkusit tento

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

To. Potřebujete se zbavit return uvnitř pro smyčky.

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

Pokud nechcete používat numpy jeho ok zkusit statistics balíček v pythonu

import statistics

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

nebo, pokud jste stále ochotni použít vlastní řešení, pak doporučujeme použít následující způsob, jak pomocí generátorové místo své komplexní přístup buggy

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

V jiných jazycích

Tato stránka je v jiných jazycích

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