问题
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