Python:如何制作具有相同*大小*bins的直方图

ast*_*ada 9 python histogram spacing binning

我有一组数据,并希望对其进行直方图.我需要这些垃圾箱具有相同的尺寸,我的意思是它们必须包含相同数量的物体,而不是具有等间距垃圾箱的更常见(numpy.histogram)问题.这自然会出现在箱子宽度的费用上,这可能 - 并且通常会 - 是不同的.

我将指定所需的箱数和数据集,获得返回的箱边.

Example:
data = numpy.array([1., 1.2, 1.3, 2.0, 2.1, 2.12])
bins_edges = somefunc(data, nbins=3)
print(bins_edges)
>> [1.,1.3,2.1,2.12]
Run Code Online (Sandbox Code Playgroud)

所以箱子都包含2个点,但它们的宽度(0.3,0.8,0.02)是不同的.

有两个限制: - 如果一组数据相同,则包含它们的bin可能更大. - 如果有N个数据并且要求M个箱,则如果N%M不为0,则将有N/M个箱加一个.

这段代码是我编写的一些代码,它适用于小型数据集.如果我有10**9 +分并希望加快这个过程怎么办?

  1 import numpy as np
  2 
  3 def def_equbin(in_distr, binsize=None, bin_num=None):
  4 
  5     try:
  6 
  7         distr_size = len(in_distr)
  8 
  9         bin_size = distr_size / bin_num
 10         odd_bin_size = distr_size % bin_num
 11 
 12         args = in_distr.argsort()
 13 
 14         hist = np.zeros((bin_num, bin_size))
 15 
 16         for i in range(bin_num):
 17             hist[i, :] = in_distr[args[i * bin_size: (i + 1) * bin_size]]
 18 
 19         if odd_bin_size == 0:
 20             odd_bin = None
 21             bins_limits = np.arange(bin_num) * bin_size
 22             bins_limits = args[bins_limits]
 23             bins_limits = np.concatenate((in_distr[bins_limits],
 24                                           [in_distr[args[-1]]]))
 25         else:
 26             odd_bin = in_distr[args[bin_num * bin_size:]]
 27             bins_limits = np.arange(bin_num + 1) * bin_size
 28             bins_limits = args[bins_limits]
 29             bins_limits = in_distr[bins_limits]
 30             bins_limits = np.concatenate((bins_limits, [in_distr[args[-1]]]))
 31 
 32         return (hist, odd_bin, bins_limits)
Run Code Online (Sandbox Code Playgroud)

aga*_*rs3 12

使用您的示例案例(2个点,6个总数据点):

from scipy import stats
bin_edges = stats.mstats.mquantiles(data, [0, 2./6, 4./6, 1])
>> array([1. , 1.24666667, 2.05333333, 2.12])
Run Code Online (Sandbox Code Playgroud)

  • 当你学习一个新术语时,它不仅仅是花花公子,然后突然间谷歌似乎又开始工作了吗?一直发生在我身上. (6认同)

Pie*_*esi 9

我还想提一下 的存在pandas.qcut,它以一种非常有效的方式进行均等的分箱。在你的情况下,它会像

data = np.array([1., 1.2, 1.3, 2.0, 2.1, 2.12])
# parameter q specifies the number of bins
qc = pd.qcut(data, q=3, precision=1)

# bin definition
bins  = qc.categories
print(bins)
>> Index(['[1, 1.3]', '(1.3, 2.03]', '(2.03, 2.1]'], dtype='object')

# bin corresponding to each point in data
codes = qc.codes
print(codes)
>> array([0, 0, 1, 1, 2, 2], dtype=int8)
Run Code Online (Sandbox Code Playgroud)