为numpy数组分配值,其中包含叠加的索引切片

4

我希望可以给数组的一些部分赋值。我已经获得了这些部分的索引,它们是元组(start_idx, end_idx)的形式。这些部分可能会重叠或者互相包含。

a = np.zeros(12)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
a[segments] = 1

结果如下:
a
>> array([1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0])

我该如何屏蔽所有分段以获得以下输出:
a
>> array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0])

你确定期望的输出是正确的吗?看起来[3]元素是错误的?难道不应该是0吗? - MSeifert
@MSeifert 看起来它包括了段落的结尾。 - Divakar
但是如何处理数字“10”呢?通常情况下,对于a = np.zeros(10),至少会引发一个IndexError异常。 - MSeifert
1
@MSeifert 猜测这是一个打字错误:a = np.zeros(12),因为最终输出似乎有12个元素。 - Divakar
@Divakar 啊,这也是一种可能性。但似乎答案排除了终点 - 至少是被接受的答案。所以我认为期望的输出可能是错误的(但错误的输入也有道理)。 - MSeifert
4个回答

2

这里有一个向量化的方法,借鉴了这篇文章的思路 -

def segment_arr(segments, L): # L being length of output array
    s = np.zeros(L,dtype=int)
    stop = segments[:,1]+1
    np.add.at(s,segments[:,0],1)
    np.add.at(s,stop[stop<len(s)],-1)
    return (s.cumsum()>0).astype(int)

运行示例 -

In [298]: segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])

In [299]: segment_arr(segments, L=12)
Out[299]: array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0])

1
至少一种能够真正产生“给定的预期输出”的解决方案。 :) - MSeifert

1

试试这个:

a = np.zeros(10)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
a[range(3)+range(1,2)+range(6,8)+range(8,10)] = 1
print (a)

我怎样才能在不手动赋值的情况下完成这个操作呢?我可以在列表生成器中创建范围,但是如何进行输入呢? - Katerina
那么在这种情况下,您将不得不通过循环来实现。 - d_void
请注意,这会在Python 3.x上抛出一个“TypeError:unsupported operand type(s) for +: 'range' and 'range'”错误。 - MSeifert

1

一种选项是简单地循环遍历,并将范围转换为实际索引:

a = np.zeros(10)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])

a[[i for s in segments for i in range(*s)]] = 1    
a
# array([ 1.,  1.,  1.,  0.,  0.,  0.,  1.,  1.,  1.,  1.])

1

只是提一下微不足道的解决方案:使用 for 循环遍历 segments 并分配给切片:

import numpy as np
a = np.zeros(12)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])

for seg in segments.tolist():  # the "tolist" is just an optimization here, you *could* omit it.
    a[seg[0]: seg[1]+1] = 1    # or just "seq[1]" if you want to exclude the end point
print(a)
# array([ 1.,  1.,  1.,  1.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接