Как рассчитать стандартное отклонение от гистограммы?(Питон, Матплотлиб) - PullRequest
0 голосов
/ 10 июня 2018

Допустим, у меня есть набор данных и я использовал matplotlib, чтобы нарисовать гистограмму указанного набора данных.

n, bins, patches = plt.hist(data, normed=1)

Как рассчитать стандартное отклонение, используя значения n и bins, которые возвращает hist()?В настоящее время я делаю это, чтобы вычислить среднее значение:

s = 0
for i in range(len(n)):
   s += n[i] * ((bins[i] + bins[i+1]) / 2) 
mean = s / numpy.sum(n)

, которое, кажется, работает нормально, так как я получаю довольно точные результаты.Однако, если я попытаюсь вычислить стандартное отклонение следующим образом:

t = 0
for i in range(len(n)):
  t += (bins[i] - mean)**2
std = np.sqrt(t / numpy.sum(n))

, мои результаты будут далеки от того, что возвращает numpy.std(data).Замена границ левой корзины на центральную точку каждой корзины тоже не изменит этого.У меня такое ощущение, что проблема в том, что значения n и bins на самом деле не содержат любую информацию о том, как отдельные точки данных распределены в каждом бункере, но о назначении, с которым я работаючетко требует, чтобы я использовал их для расчета стандартного отклонения.

Ответы [ 2 ]

0 голосов
/ 07 августа 2019

Следующий ответ эквивалентен ответу Уоррена Векессера, но, возможно, более знаком тем, кто предпочитает среднее значение в качестве ожидаемого значения:

n, bins = np.histogram(x)
mids = 0.5*(bins[1:] + bins[:-1])
probs = n / np.sum(n)

mean = np.sum(probs * mids)  
sd = np.sqrt(np.sum(probs * (mids - mean)**2)

Обратите внимание, что в определенном контексте вам может потребоваться несмещенная выборочная дисперсия, где веса не нормированы на N, а на N-1.

0 голосов
/ 10 июня 2018

Вы не взвесили вклад каждого бина с n[i].Измените приращение t на

    t += n[i]*(bins[i] - mean)**2

Кстати, вы можете упростить (и ускорить) ваши вычисления, используя numpy.average с аргументом weights.

Вот пример.Сначала сгенерируйте данные для работы.Перед вычислением гистограммы мы вычислим среднее значение выборки, дисперсию и стандартное отклонение ввода.

In [54]: x = np.random.normal(loc=10, scale=2, size=1000)

In [55]: x.mean()
Out[55]: 9.9760798903061847

In [56]: x.var()
Out[56]: 3.7673459904902025

In [57]: x.std()
Out[57]: 1.9409652213499866

Я буду использовать numpy.histogram для вычисления гистограммы:

In [58]: n, bins = np.histogram(x)

mids - середина бункеров;он имеет ту же длину, что и n:

In [59]: mids = 0.5*(bins[1:] + bins[:-1])

Оценка среднего значения представляет собой средневзвешенное значение mids:

In [60]: mean = np.average(mids, weights=n)

In [61]: mean
Out[61]: 9.9763028267760312

В этом случае оно довольно близкок среднему значению исходных данных.

Расчетная дисперсия представляет собой средневзвешенное значение квадрата разности от среднего значения:

In [62]: var = np.average((mids - mean)**2, weights=n)

In [63]: var
Out[63]: 3.8715035807387328

In [64]: np.sqrt(var)
Out[64]: 1.9676136767004677

Эта оценка находится в пределах 2% от фактического стандартного отклонения выборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...