我遇到了一个烦人的小问题。我的问题是这样的:
我有一系列介于 0 和 1 之间的数字: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
和两个边界,比如 0.25 和 0.75。
我需要一种快速而漂亮的方法来找到系列中第一个数字和最后一个数字的索引,它们在边界内,在这种情况下是 (2, 6)
到目前为止,我只提出了一种使用 for 循环和 break 命令的笨拙方法。
提前感谢您的帮助!
我遇到了一个烦人的小问题。我的问题是这样的:
我有一系列介于 0 和 1 之间的数字: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
和两个边界,比如 0.25 和 0.75。
我需要一种快速而漂亮的方法来找到系列中第一个数字和最后一个数字的索引,它们在边界内,在这种情况下是 (2, 6)
到目前为止,我只提出了一种使用 for 循环和 break 命令的笨拙方法。
提前感谢您的帮助!
如果你可以使用 numpy:
import numpy as np
data = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
max_b = .75
min_b = .25
wh = np.where((data < max_b)*(data > min_b))[0]
left, right = wh[0], wh[-1] + 1
或者简单地说(感谢 dougal):
left, right = np.searchsorted(data, [min_b, max_b])
如果你不能:
import bisect
data = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
max_b = .75
min_b = .25
left = bisect.bisect_left(data, min_b)
right = bisect.bisect_right(data, max_b)
右边加或减 1 取决于你是想data[right]
在集合中,还是data[left:right]
给你集合。
如果您的一系列数字始终排序,您可以使用该bisect
模块对端点执行二进制搜索:
>>> a = [.1, .2, .3, .4, .5, .6, .7, .8, .9]
>>> import bisect
>>> bisect.bisect_left(a, 0.25)
2
>>> bisect.bisect_right(a, 0.75) - 1
6
bisect_left(a, x)
返回位置p
,使得 的每个元素a[:p]
都小于x
,并且 的每个元素a[p:]
都大于或等于x
;这正是您想要的下限。
bisect_right
返回位置p
,使得 的每个元素a[:p]
都小于或等于x
,并且a[p:]
都大于x
。所以对于右边界,你需要减一才能得到最大的位置<= x
。