Стандартное отклонение списка

104

Я хочу найти среднее значение и стандартное отклонение 1-й, 2-й, ... цифр нескольких (Z) списков. Например, у меня есть

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

Теперь я хочу взять среднее значение и зЬе в *_Rank[0]среднее и зЬй из *_Rank[1], и т.д.
(т.е. средних и станда 1 - го разряда из всех (a..z) _rank списков,
средние и зЬе 2 - го разряда из все списки (A..Z) _rank;
среднее и стандартное значение третьей цифры ...; и т. д.).

Physics_for_all
источник
13
Привет, вирусный. Stack Overflow лучше всего работает как сайт вопросов и ответов . Вы задаете вопрос, а все остальные дают ответы. Ваш пост содержит только утверждения, без вопросов. У вас есть конкретный вопрос по программированию? Другими словами, что вы пробовали до сих пор и в чем вы застряли?
Robᵩ
2
Почему этих списков нет в словаре или что-то в этом роде?
Waleed Khan
Извините, если я неправильно передал вопрос. Я хочу взять среднее значение A_rank [0] (0.8), B_rank [0] (0.1), C_rank [0] (1.2), ... Z_rank [0]. то же самое для A_rank [1] (0.4), B_rank [1] (2.8), C_rank [1] (3.4), ... Z_rank [1].
Physics_for_all

Ответы:

153

Начиная с Python 3.4 / PEP450 , statistics moduleв стандартной библиотеке есть методstdev вычисления стандартного отклонения итераций, подобных вашему:

>>> A_rank = [0.8, 0.4, 1.2, 3.7, 2.6, 5.8]
>>> import statistics
>>> statistics.stdev(A_rank)
2.0634114147853952
Bengt
источник
39
Стоит отметить, что это, pstddevвероятно, следует использовать вместо этого, если ваш список представляет всю совокупность (т. Е. Список не является выборкой генеральной совокупности). stddevрассчитывается с использованием выборочной дисперсии и будет завышать среднее значение генеральной совокупности.
Alex Riley
4
Функции фактически вызываются stdevи pstdevне используются stdдля, standardкак можно было бы ожидать. Я не мог отредактировать сообщение, так как для редактирования нужно изменить как минимум 6 символов ...
mknaf
104

Я бы поместил A_Rankи др. В 2D NumPy массив , а затем использовал бы numpy.mean()и numpy.std()для вычисления средних и стандартных отклонений:

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
источник
2
результат numpy.std неверен. Учитывая эти значения: 20,31,50,69,80 и поместите в Excel с помощью STDEV.S (A1: A5), результат будет 25,109 НЕ 22,45.
Джим Клермонтс,
22
@JimClermonts Это не имеет ничего общего с правильностью. Независимо от того, будет ли ddof = 0 (по умолчанию, интерпретировать данные как совокупность) или ddof = 1 (интерпретировать его как образцы, т.е. оценить истинную дисперсию), зависит от того, что вы делаете.
runDOSrun
17
Чтобы еще больше прояснить суть @ runDOSrun, функция Excel и функция STDEV.P()Numpy std(ddof=0)вычисляют SD популяций или нескорректированную выборку SD, в то время как функция Excel и функция STDEV.S()Numpy std(ddof=1)вычисляют (скорректированную) выборку SD, которая равна sqrt (N / (N-1) ) умноженное на численность населения sd, где N - количество точек. Подробнее: en.m.wikipedia.org/wiki/…
binaryfunt 09
52

Вот код на чистом Python, который вы можете использовать для вычисления среднего и стандартного отклонения.

Весь приведенный ниже код основан на statisticsмодуле в 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

Примечание: для повышения точности при суммировании чисел с плавающей запятой statisticsмодуль использует настраиваемую функцию, _sumа не встроеннуюsum которую я использовал вместо нее.

Теперь у нас есть например:

>>> 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
Алекс Райли
источник
1
Не должно быть pvar=ss/(n-1)?
Ранджит Рамачандра
2
@Ranjith: если вы хотите рассчитать выборочную дисперсию (или выборочную SD), вы можете использовать n-1. Приведенный выше код предназначен для населения SD (так что есть nстепени свободы).
Alex Riley
Здравствуйте, Алекс, не могли бы вы опубликовать функцию для расчета стандартного отклонения выборки? Я ограничен Python2.6, поэтому я должен использовать эту функцию.
Venu S
@VenuS: Здравствуйте, я отредактировал stddevфункцию, чтобы она могла вычислять стандартные отклонения как выборки, так и совокупности.
Alex Riley
22

В Python 2.7.1 вы можете рассчитать стандартное отклонение, используя numpy.std()для:

  • Стандартное заполнение : просто используйте numpy.std()без дополнительных аргументов, кроме списка данных.
  • Пример стандартного значения : вам необходимо передать ddof (то есть дельта степеней свободы) равным 1, как в следующем примере:

numpy.std (<ваш-список>, ddof = 1 )

В расчетах используется делитель N - ddof , где N представляет собой количество элементов. По умолчанию ddof равен нулю.

Он вычисляет стандартную выборку, а не стандартную погоду.

Омэ
источник
8

Используя python, есть несколько методов:

import statistics as st

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

Подход 1 - использование функции

stdev = st.pstdev(data)

Подход 2: вычислить дисперсию и извлечь из нее квадратный корень

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

Подход 3: использование базовой математики

mean = sum(data)/n
variance = sum([((x - mean) ** 2) for x in X]) / n
stddev = variance ** 0.5

print("{0:0.1f}".format(stddev))

Примечание:

  • variance вычисляет дисперсию выборочной совокупности
  • pvariance вычисляет дисперсию всего населения
  • аналогичные различия между stdevиpstdev
панкадж
источник
5

чистый код Python:

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))
Элад Иехезкель
источник
10
В этом однострочнике нет ничего «чистого». Фу. Вот более питоническая версия:sqrt(sum((x - mean)**2 for x in lst) / len(lst))
DBrowne
3

В других ответах рассказывается, как сделать std dev на python в достаточной степени, но никто не объясняет, как выполнить описанный вами странный обход.

Я предполагаю, что Аризона - это все население. Если не увидишь Оме Ответ о том, как делать выводы из образца.

Итак, чтобы получить стандартное отклонение / среднее значение первой цифры каждого списка, вам понадобится что-то вроде этого:

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

Чтобы сократить код и обобщить его до любой n-й цифры, используйте следующую функцию, которую я сгенерировал для вас:

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

Теперь вы можете просто получить стандартное и среднее значение всех n-х разрядов от А до Я следующим образом:

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

#mean
numpy.mean(getAllNthRanks(n))
Сами Бенчериф
источник
Для всех, кого это интересует, я сгенерировал функцию, используя этот беспорядочный однострочник:str([chr(x)+'_rank[n]' for x in range(65,65+26)]).replace("'", "")
Сами Бенчериф