Работа с ячейками гистограммы Python

Я пытаюсь найти медиану значений в диапазоне ячеек, сгенерированном функцией np.histrogram. Как мне выбрать значения только в диапазоне ячеек и работать с этими конкретными значениями? Ниже приведен пример моих данных и того, что я пытаюсь сделать:

x = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]

значения y могут иметь любое значение x, связанное с ними, например:

hist, bins = np.histogram(x)
hist = [129, 126, 94, 133, 179, 206, 142, 147, 90, 185] 
bins = [0.,         0.09999926, 0.19999853, 0.29999779, 0.39999706,
        0.49999632, 0.59999559, 0.69999485, 0.79999412, 0.8999933,
        0.99999265]

Итак, я пытаюсь найти среднее значение y из 129 значений в первом сгенерированном бине и т. д.


person hlku2334    schedule 14.11.2018    source источник
comment
Мне немного сложно поверить в вашу гистограмму, но я понимаю вашу точку зрения.   -  person Mad Physicist    schedule 14.11.2018


Ответы (3)


Один из способов с pandas.cut():

>>> import pandas as pd
>>> import numpy as np
>>> np.random.seed(444)

>>> x = np.random.randint(0, 25, size=100)
>>> _, bins = np.histogram(x)
>>> pd.Series(x).groupby(pd.cut(x, bins)).median()
(0.0, 2.4]       2.0
(2.4, 4.8]       3.0
(4.8, 7.2]       6.0
(7.2, 9.6]       8.5
(9.6, 12.0]     10.5
(12.0, 14.4]    13.0
(14.4, 16.8]    15.5
(16.8, 19.2]    18.0
(19.2, 21.6]    20.5
(21.6, 24.0]    23.0
dtype: float64

Если вы хотите остаться в NumPy, вы можете проверить np.digitize().

person Brad Solomon    schedule 14.11.2018

Вы можете сделать это, нарезая отсортированную версию ваших данных, используя счетчики в качестве индексов:

x = np.random.rand(1000)
hist,bins = np.histogram(x)

ix = [0] + hist.cumsum().tolist()
# if don't mind sorting your original data, use x.sort() instead
xsorted = np.sort(x)
ix = [0] + hist.cumsum()
[np.median(x[i:j]) for i,j in zip(ix[:-1], ix[1:])]

который выведет медианы из стандартного списка Python.

person tel    schedule 14.11.2018
comment
Взгляните на np.split - person Mad Physicist; 14.11.2018

np.digitize и np.searchsorted сопоставит ваши данные с бинами. Последний предпочтительнее в этой ситуации, потому что он делает меньше ненужных проверок (можно с уверенностью предположить, что ваши корзины отсортированы).

Если вы посмотрите документацию np.histogram (Примечания раздел), вы заметите, что все корзины справа полуоткрыты (кроме последней). Это означает, что вы можете сделать следующее:

x = np.abs(np.random.normal(loc=0.75, scale=0.75, size=10000))
h, b = np.histogram(x)
ind = np.searchsorted(b, x, side='right')

Теперь ind содержит метку для каждого числа, указывающую, к какой ячейке оно принадлежит. Вы можете вычислить медианы:

m = [np.median(x[ind == label]) for label in range(b.size - 1)]

Если вы можете сортировать входные данные, ваша работа упрощается, поскольку вы можете использовать представления вместо извлечения данных для каждого бина с помощью маскирования. В этом случае хорошим выбором будет np.split:

x.sort()
sections = np.split(x, np.cumsum(h[:-1]))
m = [np.median(arr) for arr in sections]
person Mad Physicist    schedule 14.11.2018