过滤直方图边缘和计数

时间:2016-02-12 02:50:46

标签: python python-3.x numpy matplotlib histogram

考虑一个返回百分比的numpy数组的直方图计算:

# 500 random numbers between 0 and 10,000
values = np.random.uniform(0,10000,500)

# Histogram using e.g. 200 buckets
perc, edges = np.histogram(values, bins=200,
                           weights=np.zeros_like(values) + 100/values.size)

以上返回两个数组:

  • perc在每对连续%edges[ix]中包含edges[ix+1](即百分比)的值。
  • edgeslen(hist)+1

现在,我想要过滤percedges,这样我最终只会在新范围{{1}中包含的百分比和边缘}}。 “

也就是说,我想使用[m, M]perc子数组,对应edges内的值区间。不用说,新的百分比数组仍然指的是输入数组的总分数。我们只想过滤[m, M]perc以获得正确的子数组。

如何对edgesperc进行后处理?

edgesm的值可以是任意数量的。在上面的例子中,我们可以假设,例如Mm = 0

2 个答案:

答案 0 :(得分:2)

m = 0; M = 200
mask = [(m < edges) & (edges < M)]
>>> edges[mask]
array([  37.4789683 ,   87.07491593,  136.67086357,  186.2668112 ])

让我们处理较小的数据集,以便更容易理解:

np.random.seed(0)
values = np.random.uniform(0, 100, 10)
values.sort()
>>> values
array([ 38.34415188,  42.36547993,  43.75872113,  54.4883183 ,
        54.88135039,  60.27633761,  64.58941131,  71.51893664,
        89.17730008,  96.36627605])

# Histogram using e.g. 10 buckets
perc, edges = np.histogram(values, bins=10,
                           weights=np.zeros_like(values) + 100./values.size)

>>> perc
array([ 30.,   0.,  20.,  10.,  10.,  10.,   0.,   0.,  10.,  10.])

>>> edges
array([ 38.34415188,  44.1463643 ,  49.94857672,  55.75078913,
        61.55300155,  67.35521397,  73.15742638,  78.9596388 ,
        84.76185122,  90.56406363,  96.36627605])

m = 0; M = 50
mask = (m <= edges) & (edges < M)
>>> mask
array([ True,  True,  True, False, False, False, False, False, False,
       False, False], dtype=bool)

>>> edges[mask]
array([ 38.34415188,  44.1463643 ,  49.94857672])

>>> perc[mask[:-1]][:-1]
array([ 30.,   0.])

m = 40; M = 60
mask = (m < edges) & (edges < M)
>>> edges[mask]
array([ 44.1463643 ,  49.94857672,  55.75078913])
>>> perc[mask[:-1]][:-1]
array([  0.,  20.])

答案 1 :(得分:1)

那么你可能需要一些数学知识。这些箱子的间距相等,因此您可以通过使用每个箱子的宽度来确定哪个箱子是第一个包含的箱子,哪个箱子是最后一个箱子:

bin_width = edges[1] - edges[0]

现在计算第一个和最后一个有效的bin:

first = math.floor((m - edges[0]) / bin_width) + 1 # How many bins from the left
last = math.floor((edges[-1] - M) / bin_width) + 1 # How many bins from the right

(如果您想要包含包含mM的bin,请忽略两者的+1 - 但请注意,您不会为第一个和最后一个结束负值!)

现在您知道要包含多少个箱子:

valid_edges = edges[first:-last]
valid_perc = perc[first:-last]

这将排除第一个first点和最后last个点。

可能是因为我没有对圆角进行足够的重视,并且包含了“一个一个”错误,但我认为这个想法很合理。 : - )

您可能需要捕获M > edges[-1]之类的特殊情况,但为了便于阅读,我没有将其包括在内。

或者如果箱子的间隔不均匀,则使用布尔掩码而不是计算:

first = edged[edges < m].size + 1
last = edged[edges > M].size + 1