Python identify in which interval the numbers are

核能气质少年 提交于 2019-12-12 01:54:18

问题


I would like to run a for loop in Python that checks, given a certain amount of intervals, for each element of the loop, in which interval it is. For instance:

interval_1 = [1; 10]
interval_2 = [11; 58]

I was looking for a more elegant solution than a large if/elif/else condition, for instance my idea was to load an excel worksheet containing n couples of numbers corresponding to the interval extremities, and use a function that finds me for in which interval my number is.

Does a similar function exist in Python? Or eventually how could this be done?


回答1:


numpy has nice support for this without having to write a for loop:

import numpy as np

data = np.array([0.2, 6.4, 3.0, 1.6])
bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
cats = np.digitize(data, bins)
cats
# array([1, 4, 3, 2])

If you insist on a for loop, just iterate over the elements to bin, and the bins:

data = [0.2, 6.4, 3.0]
bins = [(0.0, 1.0), (1.0, 4.0), (4.0, 10.0)]  # assumed (lower, upper] format
cats = []

for elem in data:
    for idx, bounds in enumerate(bins, start=1):
        if bounds[0] < elem <= bounds[1]:
            cats.append(idx)
            break
    else:
        raise ValueError('No bin for {}'.format(elem))

The above uses tuples to specify the bin ranges (like your example), but that's not technically necessary (e.g. the numpy code). You could store just the cutoffs and compare adjacent elements from cutoffs[:-1].




回答2:


Here's a solution that should run faster if you have a very large list of ranges. It uses python's bisect module to do a binary search to quickly find the range in which the item belongs.

For this example I'm using the ranges 2..5, 7..9 and 13..13.

The code checks whether all numbers from 0 to 14 is in one of the supplied ranges.

Code:

from bisect import *

ranges = [2, 5, 7, 9, 13, 13]   # Using this convention: 2..5, 7..9, 13..13. Assume ranges inclusive.
for item in range(15):
    valid = False
    L = (bisect_left(ranges, item) // 2) * 2
    if L+1 < len(ranges):
        valid = ranges[L] <= item and ranges[L + 1] >= item
    print(item, valid)

Output:

0 False
1 False
2 True
3 True
4 True
5 True
6 False
7 True
8 True
9 True
10 False
11 False
12 False
13 True
14 False


来源:https://stackoverflow.com/questions/36479374/python-identify-in-which-interval-the-numbers-are

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!