2

我有一个关于用所需的 bin 宽度重新组合数字列表的问题。这基本上是频率直方图的作用,但我不想要图,只想要 bin 编号和每个 bin 的出现次数。

到目前为止,我已经编写了一些我想要的代码,但是效率不是很高。给定一个 list a,为了用等于 3 的 bin-width 重新组合它,我写了以下内容:

import os, sys, math
import numpy as np

# list of numbers
a = list(range(3000))

# number of entries
L = int(len(a))

# desired bin width
W = 3

# number of bins with width W
N = int(L/W)

# definition of new empty array
a_rebin = np.zeros((N, 2))

# cycles to populate the new rebinned array
for n in range(0,N):
    k = 0
    for i in range(0,L):
        if a[i] >= (W*n) and a[i] < (W+W*n):
            k = k+1
    a_rebin[n]=[W*n,k]

# print
print a_rebin

现在,这正是我想要的,但我认为它不是那么聪明,因为它会读取整个列表N时间,N以及垃圾箱的数量。对于小列表来说很好。但是,由于我必须处理非常大的列表和相当小的 bin 宽度,这会转化为巨大的值,N并且整个过程需要很长时间(数小时......)。你有什么想法来改进这段代码吗?先感谢您!

4

2 回答 2

4

如果您使用a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],您的解决方案是:

[[ 0. 3.]
[ 3. 3.]
[ 6. 3.]]

你如何解释这个?间隔是 0..2、3..5、6..8?我认为你错过了一些东西。

使用numpy.histogram()

hist, bin_edges = numpy.histogram(a, bins=int(len(a)/W))
print(hist)
print(bin_edges)

输出:

[3 3 4]
[ 0. 3. 6. 9.]

我们在 bin_edges 中有 4 个值:0、3、6 和 9。除了最后一个(最右边的)bin 之外,所有的 bin 都是半开的。这意味着我们有 3 个区间 [0,3)、[3,6) 和 [6,9],每个 bin 中有 3、3 和 4 个元素。
您可以定义自己的垃圾箱。

import numpy
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
bins=[0,1,2]
hist, bin_edges = numpy.histogram(a, bins=bins)
print(hist)
print(bin_edges)

输出:

[1 2]
[0 1 2]

现在您在 [0 ,1) 中有 1 个元素,在 [1,2] 中有 2 个元素。

于 2016-08-04T17:07:48.470 回答
-1

Numpy 有一个名为np.histogram的方法可以为您完成工作。它也可以很好地扩展。

于 2016-08-04T16:46:13.497 回答