重新排列 python 中的数字列表

rebinning a list of numbers in python

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

到目前为止,我已经编写了一些代码来执行我想要的操作,但效率不是很高。给定一个列表 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。这适用于小列表。但是,由于我必须处理非常大的列表和相当小的 bin-widths,这会转化为 N 的巨大值,并且整个过程需要很长时间(数小时...)。您有任何改进此代码的想法吗?提前致谢!

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

如果你使用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 个元素。