来自 True 值范围(开始和结束)的布尔列表,不使用 for 循环
Posted
技术标签:
【中文标题】来自 True 值范围(开始和结束)的布尔列表,不使用 for 循环【英文标题】:A boolean list from ranges of True values (start and end), without using a for loop 【发布时间】:2021-11-26 04:18:20 【问题描述】:例如,我有这个包含范围的列表。
x=[[1,4],
[6,7],
[9,9]]
其中每个项目的第一个值(例如[1,4]
)是开始位置(1
),第二个值是结束(4
)位置。
我想将此范围列表转换为布尔列表,其中如果位置位于上面列表中指示的(任何)范围(即开始和结束位置)之间,则值为True
,否则值应该是False
。
[False, True, True, True, True, False, True, True, False, True]
这显然可以使用 for 循环来实现。但是,我正在寻找其他单行选项。理想情况下,我正在寻找一些也适用于熊猫系列的方法。
注意:这本质上是这个问题的相反问题:Get ranges of True values (start and end) in a boolean list (without using a for loop)
【问题讨论】:
确定映射到True
的逻辑是什么?为什么您的布尔列表有 10 个项目,而原始列表有 6 个?
@ddejohn 我同意它没有很好的格式或解释,但我想逻辑类似于另一个问题here
【参考方案1】:
使用 numpy 的一种有希望的有效方法:
low, high = np.array(x).T[:,:, None] # rearrange the limits into a 3d array in a convenient shape
a = np.arange(high.max() + 1) # make a range from 0 to 9
print(((a >= low) & (a <= high)).any(axis=0))
在 python 循环中编辑数组的替代方法:
result = np.zeros(np.array(x).max() + 1, dtype=bool)
for start, end in x:
result[start:end+1] = True
这可能会更快,具体取决于编辑数组切片相对于 numpy 2d 矩阵比较的速度。
【讨论】:
有什么复杂性?我认为 O(max(high) * len(high)),所以相当二次? 也许是矩阵数学大 O 复杂度方面的专家可以发表评论。从某种意义上说,它将所有工作委托给用优化良好的 C 语言编写的 numpy 向量函数,避免任何 python 循环,这是一种高效的方法。如果首先对范围进行排序,或者假定范围已经排序,则可能会有更好的解决方案。 我认为我们不需要“专家”:-)。你的a >= low
是一个二维数组,宽度为 max(high),高度为 len(high),对吧?时间肯定是线性的。该行代码中的其他操作也是如此。
而循环解决方案只需要 O(max(high))。以上是关于来自 True 值范围(开始和结束)的布尔列表,不使用 for 循环的主要内容,如果未能解决你的问题,请参考以下文章