Python:检查一个值属于哪个区间

20 投票
3 回答
19678 浏览
提问于 2025-04-17 16:19

我有一组数值和一组区间边界。现在我需要检查每个数值属于哪个区间。有没有比一个个遍历数值,再遍历区间,检查这个数值是否在当前区间内的方式更简洁一些呢?比如:

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 个回答

4

首先,你的代码在值等于某个区间边界的时候会出错。

你需要把

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

改成某个地方加上一个<=符号。

之后,使用一下bisect模块

import bisect
bisect.bisect(x, bins)

或者用bisect.bisect_right

这取决于你想在值处于区间边界时选择高的区间还是低的区间。

5

也许这能帮助你找到正确的方向:

>>> 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]
41

可能有点晚了,但为了将来参考,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)。需要注意的是,这个函数也会把那些超出你设定的第一个和最后一个区间边界的值进行分类:

>>> 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)

撰写回答