在直方图 bins 上操作 Python

Operating on histogram bins Python

我试图在 np.histrogram 函数生成的 bin 范围内找到值的中值。我如何 select 仅在 bin 范围内的值并对这些特定值进行操作?下面是我的数据示例和我正在尝试做的事情:

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]

所以,我试图在生成的第一个 bin 中找到 129 个值的中值 y 值,等等。

一种方法是 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()

您可以通过使用计数作为索引对数据的排序版本进行切片来做到这一点:

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 列表。

np.digitize and np.searchsorted 会将您的数据与 bin 匹配。在这种情况下后者更可取,因为它减少了不必要的检查(可以安全地假定您的垃圾箱已分类)。

如果您查看 np.histogram 的文档(注释部分),您会注意到右边的 bin 都是半开的(最后一个除外)。这意味着您可以执行以下操作:

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

如果您能够对输入数据进行排序,您的工作就会变得更容易,因为您可以使用视图而不是使用掩码为每个 bin 提取数据。 np.split 在这种情况下是一个不错的选择:

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