Python:检查值属于哪个bin

时间:2013-02-19 00:41:09

标签: python range binning

我有一个值列表和一个bin边缘列表。现在我需要检查它们属于哪个bin的所有值。是否有更多的pythonic方式,而不是迭代值,然后遍历bin并检查值是否属于当前bin,如:

my_list = [3,2,56,4,32,4,7,88,4,3,4]
bins = [0,20,40,60,80,100]

for i in my_list:
    for j in range(len(bins)):
        if bins(j) < i < bins(j+1):
            DO SOMETHING

对我来说这看起来不太好看。 谢谢!

3 个答案:

答案 0 :(得分:22)

可能为时已晚,但为了将来参考,numpy有一个功能就是这样:

  

http://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html

>>> my_list = [3,2,56,4,32,4,7,88,4,3,4]
>>> bins = [0,20,40,60,80,100]
>>> np.digitize(my_list,bins)
array([1, 1, 3, 1, 2, 1, 1, 5, 1, 1, 1])

结果是一个索引数组,对应于来自bin的bin,来自my_list的每个元素也属于。 请注意,该函数还会将值放在第一个和最后一个bin边缘之外的值:

>>> my_list = [-5,200]
>>> np.digitize(my_list,bins)
array([0, 6])

Pandas也有类似的东西:

  

http://pandas.pydata.org/pandas-docs/dev/basics.html#discretization-and-quantiling

>>> pd.cut(my_list, bins)
Categorical: 
array(['(0, 20]', '(0, 20]', '(40, 60]', '(0, 20]', '(20, 40]', '(0, 20]',
       '(0, 20]', '(80, 100]', '(0, 20]', '(0, 20]', '(0, 20]'], dtype=object)
Levels (5): Index(['(0, 20]', '(20, 40]', '(40, 60]', '(60, 80]',
                   '(80, 100]'], dtype=object)

答案 1 :(得分:3)

也许这有助于您走上正轨:

>>> import itertools
>>> my_list = [3,2,56,4,32,4,7,88,4,3,4]
>>> for k, g in itertools.groupby(sorted(my_list), lambda x: x // 20 * 20):
...     print k, list(g)
... 
0 [2, 3, 3, 4, 4, 4, 4, 7]
20 [32]
40 [56]
80 [88]

答案 2 :(得分:3)

首先,当值等于bin边界时,你的代码将失败 -

更改

if bins(j) < i < bins(j+1):

在某处有一个<=标志。

之后,使用bisect模块

import bisect
bisect.bisect(x, bins)

bisect.bisect_right

取决于当值位于bin边界时是否更喜欢使用较高或较低的bin。