为了账号安全,请及时绑定邮箱和手机立即绑定

使用NumPy查找条件为True的跨度

使用NumPy查找条件为True的跨度

米琪卡哇伊 2021-03-28 15:11:19
假设我有一个numpy数组,我需要找到条件为True的跨度/范围。例如,我有以下数组,我试图在其中查找项目大于1的跨度:[0, 0, 0, 2, 2, 0, 2, 2, 2, 0]我需要找到索引(开始,停止):(3, 5) (6, 9)我能够实现的最快的方法是创建一个布尔数组:truth = data > threshold然后使用numpy.argmin和遍历数组numpy.argmax以查找开始和结束位置。    pos = 0    truth = container[RATIO,:] > threshold    while pos < len(truth):        start = numpy.argmax(truth[pos:]) + pos + offset        end = numpy.argmin(truth[start:]) + start  + offset        if not truth[start]:#nothing more            break        if start == end:#goes to the end            end = len(truth)        pos = end但这对于我数组中的数十亿个位置来说太慢了,而且我发现的跨度通常只是连续几个位置。有谁知道找到这些跨度的更快方法?
查看完整描述

2 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

怎么样 首先获取您拥有的布尔数组:


In [11]: a

Out[11]: array([0, 0, 0, 2, 2, 0, 2, 2, 2, 0])


In [12]: a1 = a > 1

使用以下命令将其向左移动一个(以获取每个索引的下一个状态)roll:


In [13]: a1_rshifted = np.roll(a1, 1)


In [14]: starts = a1 & ~a1_rshifted  # it's True but the previous isn't


In [15]: ends = ~a1 & a1_rshifted

如果非零,则是每个True批次的开始(或分别是结束批次):


In [16]: np.nonzero(starts)[0], np.nonzero(ends)[0]

Out[16]: (array([3, 6]), array([5, 9]))

并将它们压缩在一起:


In [17]: zip(np.nonzero(starts)[0], np.nonzero(ends)[0])

Out[17]: [(3, 5), (6, 9)]


查看完整回答
反对 回复 2021-04-02
?
慕仙森

TA贡献1827条经验 获得超7个赞

如果您有权访问scipy库:


您可以使用scipy.ndimage.measurements.label标识任何非零值区域。它返回一个数组,其中每个元素的值是原始数组中某个范围或范围的ID。


然后,您可以使用scipy.ndimage.measurements.find_objects返回提取这些范围所需的切片。您可以直接从这些片访问开始/结束值。


在您的示例中:


from numpy import array

from scipy.ndimage.measurements import label, find_objects


data = numpy.array([0, 0, 0, 2, 2, 0, 2, 2, 2, 0])


labels, number_of_regions = label(a)

ranges = find_objects(labels)


for identified_range in ranges:

    print identified_range[0].start, identified_range[0].stop

您应该看到:


3 5

6 9

希望这可以帮助!


查看完整回答
反对 回复 2021-04-02
  • 2 回答
  • 0 关注
  • 277 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信