在Python中从头开始构建一个桶列表直方图

时间:2013-02-05 16:22:22

标签: python histogram

我正在处理Think Python,而且还有一个exercise,您可以在其中编写执行以下操作的函数:

  • 作为参数:L(数字列表)和n(和int)
  • n子列表的形式返回直方图
    • 每个子列表代表L中数字所涵盖范围的细分,并包含一个int,表示L中有多少元素落入该细分中

因此,我们正在查看一系列数字,将该范围切换为n相等的存储桶,并使用这些存储桶构建直方图。本练习前面的部分显示了在处理区间[0.0,1.0)中的随机浮点列表时如何构建此类函数。它查看元素在该区间内的位置(这只是它的值),将其乘以n,并转换为int(在过程中截断)。这会在[0,n)中产生一个int,这是适当的桶索引。

这里的不同之处在于我们没有在预定(且方便)的时间间隔内工作。这就是我想出来的。我想知道是否有更优雅的方式来做到这一点。我将我的间隔计算为max(L) - min(L),但是必须添加一些额外的内容,否则L中的最大元素会得到一个n的索引(超出范围),而它应该得到n - 1.我打了个额外的extraBit

def histogram(L, n):
    hist = [0] * numBuckets
    minVal = min(L)
    maxVal = max(L)
    extraBit = .0000000000001
    interval = (maxVal - minVal) + extraBit

    for i in L:
        placement = (i - minVal) / interval
        index = int(placement * numBuckets)
        hist[index] = hist[index] + 1

    return hist

有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

我上周写了自己的文章:

def frequency_count(itt, nr_bins, minn=None, maxx=None):
    ret = []
    if minn == None:
        minn = min(itt)
    if maxx == None:
        maxx = max(itt)
    binsize = (maxx - minn) / float(nr_bins) #man, do I hate int division

    #construct bins
    ret.append([float("-infinity"), minn, 0]) #-inf -> min
    for x in range(0, nr_bins):
        start = minn + x * binsize
        ret.append([start, start+binsize, 0])
    ret.append([maxx, float("infinity"), 0]) #maxx -> inf

    #assign items to bin
    for item in itt:
        for binn in ret:
            if binn[0] <= item < binn[1]:
                binn[2] += 1        
    return ret 

这个允许你取一个值而不是整个范围。它通过添加-inf-&gt; min和max-&gt; inf catchall存储桶来修复溢出问题。我不知道这对你来说是否可以接受。