Desvio padrão de uma lista

103

Quero encontrar a média e o desvio padrão do primeiro, segundo, ... dígitos de várias listas (Z). Por exemplo, eu tenho

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 )...

Agora eu quero pegar a média e o padrão de *_Rank[0], a média e o padrão de *_Rank[1], etc.
(ou seja: média e padrão do primeiro dígito de todas as listas (A..Z) _rank;
a média e padrão do 2º dígito de todas as listas (A..Z) _rank;
a média e o padrão do terceiro dígito ...; etc).

physics_for_all
fonte
13
Olá, viral. Stack Overflow funciona melhor como um site de perguntas e respostas . Você faz uma pergunta e todo mundo dá as respostas. Sua postagem contém apenas declarações, sem perguntas. Você tem uma pergunta específica de programação? Em outras palavras, o que você tentou até agora e onde você está preso?
Robᵩ
2
Por que essas listas não estão em um dicionário ou algo assim?
Waleed Khan
Desculpe se eu não transmiti a pergunta corretamente. Quero obter a média de A_rank [0] (0,8), B_rank [0] (0,1), C_rank [0] (1,2), ... Z_rank [0]. o mesmo para A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1].
physics_for_all

Respostas:

150

Desde Python 3.4 / PEP450, existe um statistics modulena biblioteca padrão, que tem um métodostdev para calcular o desvio padrão de iteráveis ​​como o seu:

>>> A_rank = [0.8, 0.4, 1.2, 3.7, 2.6, 5.8]
>>> import statistics
>>> statistics.stdev(A_rank)
2.0634114147853952
Bengt
fonte
38
É importante ressaltar que pstddevprovavelmente deve ser usado se sua lista representar toda a população (ou seja, a lista não é uma amostra de uma população). stddevé calculado usando a variância da amostra e superestimará a média da população.
Alex Riley
4
As funções são realmente chamadas stdeve pstdevnão usam stdpara standardcomo seria de se esperar. Não consegui editar a postagem, pois as edições precisam modificar pelo menos 6 caracteres ...
mknaf
104

Eu colocaria A_Ranket al em uma matriz NumPy 2D e, em seguida, usaria numpy.mean()e numpy.std()para calcular as médias e os desvios padrão:

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 ])
NPE
fonte
2
o resultado de numpy.std não está correto. Dados estes valores: 20,31,50,69,80 e colocados no Excel usando STDEV.S (A1: A5) o resultado é 25.109 NÃO 22,45.
Jim Clermonts,
22
@JimClermonts Não tem nada a ver com correção. Se ddof = 0 (padrão, interpretar dados como população) ou ddof = 1 (interpretar como amostras, isto é, estimar a variação verdadeira) depende do que você está fazendo.
runDOSrun de
17
Para esclarecer ainda mais o ponto de @ runDOSrun, a função Excel STDEV.P()e a função Numpy std(ddof=0)calculam o sd da população , ou amostra sd não corrigida , enquanto a função Excel STDEV.S()e a função Numpy std(ddof=1)calculam a amostra sd (corrigida) , que é igual a sqrt (N / (N-1) ) vezes o dp da população, onde N é o número de pontos. Veja mais: en.m.wikipedia.org/wiki/…
binaryfunt
52

Aqui está um código Python puro que você pode usar para calcular a média e o desvio padrão.

Todo o código abaixo é baseado no statisticsmódulo em 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 maior precisão ao somar flutuações, o statisticsmódulo usa uma função personalizada _sumem vez da integrada sumque usei em seu lugar.

Agora temos por exemplo:

>>> 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
Alex Riley
fonte
1
Não deveria ser pvar=ss/(n-1)?
Ranjith Ramachandra
2
@Ranjith: se você deseja calcular a variância da amostra (ou SD da amostra), você pode usar n-1. O código acima é para o SD da população (portanto, há ngraus de liberdade).
Alex Riley
Olá Alex, Você poderia postar a função para calcular o desvio padrão da amostra? Estou limitado pelo Python2.6, então tenho que retransmitir nesta função.
Venu S,
@VenuS: Olá, editei a stddevfunção para que ela possa calcular os desvios padrão da amostra e da população.
Alex Riley,
22

No Python 2.7.1, você pode calcular o desvio padrão usando numpy.std()para:

  • População std : Basta usar numpy.std()sem argumentos adicionais além da sua lista de dados.
  • Padrão de amostra : você precisa passar ddof (ou seja, graus delta de liberdade) definido como 1, como no exemplo a seguir:

numpy.std (<sua lista>, ddof = 1 )

O divisor usado nos cálculos é N - ddof , onde N representa o número de elementos. Por padrão, ddof é zero.

Ele calcula o padrão da amostra em vez do padrão da população.

Ome
fonte
8

Usando python, aqui estão alguns métodos:

import statistics as st

n = int(input())
data = list(map(int, input().split()))

Abordagem1 - usando uma função

stdev = st.pstdev(data)

Abordagem 2: calcular a variância e obter a raiz quadrada dela

variance = st.pvariance(data)
devia = math.sqrt(variance)

Abordagem 3: usando matemática básica

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 a variação da população de amostra
  • pvariance calcula a variância de toda a população
  • diferenças semelhantes entre stdevepstdev
pankaj
fonte
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))
Elad Yehezkel
fonte
10
Não há nada de "puro" naquele 1-liner. Que nojo. Aqui está uma versão mais sqrt(sum((x - mean)**2 for x in lst) / len(lst))
pítônica
3

As outras respostas cobrem como fazer o std dev em python suficientemente, mas ninguém explica como fazer a travessia bizarra que você descreveu.

Vou assumir que AZ é toda a população. Se não, veja a resposta de Ome sobre como inferir de uma amostra.

Portanto, para obter o desvio padrão / média do primeiro dígito de cada lista, você precisaria de algo assim:

#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 encurtar o código e generalizá-lo para qualquer enésimo dígito, use a seguinte função que gerei para você:

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]] 

Agora você pode simplesmente obter o padrão e a média de todas as enésimas casas de AZ, assim:

#standard deviation
numpy.std(getAllNthRanks(n))

#mean
numpy.mean(getAllNthRanks(n))
Samy Bencherif
fonte
Para qualquer interessado, gerei a função usando este one-liner confuso:str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
Samy Bencherif