查看 index 是否包含在切片对象中

See if index is contained within a slice object

提问人:Greedo 提问时间:11/27/2021 最后编辑:Greedo 更新时间:11/27/2021 访问量:214

问:

我有一个这样的枚举:

class AgeCategory(Enum):
    Child = slice(None, 16)
    YoungAdult = slice(16, 25)
    ...
    Old = slice(85, None) 

它基本上提供了每个类别的年龄范围(以年为单位)。

我想要一个函数来检查某个值对应于哪个年龄范围。这是我的想法:

def get_category(age: int) -> AgeCategory:
    for age_range in AgeCategory:
         if age in age_range.value #check if it's in the slice for that enum
             return age_range
    else:
        assert False, "unreachable"

但是失败了。OFC 我可以做这样的事情:assert 5 in slice(1,10)

s: slice = age_range.value
if s.start <= age < s.stop: #bounds check
    return age_range

但这忽略了步骤论点,感觉就像重新发明轮子一样。


用什么方式来表达这些年龄范围?它们被用作如下切片:

ya_data = np.sum(some_data[AgeCategory.YoungAdult])
python-3.x numpy 切片 序列 成员资格

评论

0赞 darth baba 11/27/2021
可悲的是,slice() 不返回可迭代对象,正如文档中提到的 itertools.islice() 返回一个可迭代对象,但不适用于 NumPy,因为它返回元素的可迭代对象而不是索引,您可以尝试,但您必须在开始和停止中处理 Noneif age in list(range(age_range.start, age_range.stop, age_range.step))
1赞 hpaulj 11/27/2021
A 只是一个用于开始、停止、步进值的容器。它没有提供太多功能。我会用它来做一个,或者也许并测试一下。slicearangelist(range())

答:

1赞 dankal444 11/27/2021 #1

在你的例子中,它并不那么重要,但这应该比使用大切片时的迭代更快:

a_slice = slice(4, 15, 3)
def is_in_slice(a_slice, idx):
    if idx < a_slice.start or idx >= a_slice.stop:
        return False
    step = a_slice.step if a_slice.step else 1
    if (idx - a_slice.start) % step == 0:
        return True
    else:
        return False
    
test_array = np.where([is_in_slice(a_slice, idx) for idx in range(20)])[0]
print(test_array)
[ 4  7 10 13]

并测试非常大的切片:

a_big_slice = slice(0, 1_000_000_000_000, 5)
print(is_in_slice(a_big_slice, 999_000_000_005))
print(is_in_slice(a_big_slice, 999_000_000_004))
True
False
1赞 hpaulj 11/27/2021 #2

使用样品切片:

In [321]: child=slice(None,16,4)

我正在考虑将其扩展为列表或数组。但无法处理:arangeNone

In [323]: np.arange(child.start,child.stop,child.step)
Traceback (most recent call last):
  File "<ipython-input-323-b2d245f287ff>", line 1, in <module>
    np.arange(child.start,child.stop,child.step)
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'

np.r_能。在这里,numpy 开发人员已经完成了翻译所有切片选项的所有工作:

In [324]: np.r_[child]
Out[324]: array([ 0,  4,  8, 12])
In [325]: 3 in _
Out[325]: False
In [327]: 4 in __
Out[327]: True

它可能不是最快的,但似乎是最通用的方法 - 不需要你做很多工作。