根据起始和结束位置列表构建Numpy索引
我有两个大小完全相同的一维数组(numpy.array),一个数组里是起始索引的位置,另一个数组里是结束索引的位置(你也可以理解为我有一个起始位置的列表和一个窗口长度的列表)。如果有必要的话,起始和结束位置形成的切片是不会重叠的。我想知道如何利用这些起始和结束位置来为另一个数组创建索引,而不需要使用循环。
举个例子:
import numpy as np
start = np.array([1,7,20])
end = np.array([3,10,25])
想要引用
somearray[1,2,7,8,9,20,21,22,23,24])
4 个回答
0
这样做怎么样:
>>> import numpy as np
>>> start = np.array([1,7,20])
>>> end = np.array([3,10,25])
>>> na=np.fromiter(sum([range(s,e) for s,e in zip(start,end)],[]),np.int)
>>> na
array([ 1, 2, 7, 8, 9, 20, 21, 22, 23, 24])
这样做的好处有两个:1)不需要中间的numpy浮点数组;2)最终得到的数组是整数,这样可以更高效地处理其他的numpy数组。
2
Numpy的arange
函数可以创建每一个单独的序列,所以你只需要把它们连接在一起。这样做怎么样呢?
In [11]: idx = np.hstack([np.arange(s,e) for s,e in zip(start, end)])
In [12]: idx
Out[12]: array([ 1, 2, 7, 8, 9, 20, 21, 22, 23, 24])
然后你就可以通过somearray[idx]
来访问这些数据了。
7
我会使用
np.r_[tuple(slice(s, e) for s, e in zip(start, end))]
补充说明:这里有一个不使用Python循环的解决方案:
def indices(start, end):
lens = end - start
np.cumsum(lens, out=lens)
i = np.ones(lens[-1], dtype=int)
i[0] = start[0]
i[lens[:-1]] += start[1:]
i[lens[:-1]] -= end[:-1]
np.cumsum(i, out=i)
return i
这个方法只创建了一个临时的NumPy数组(lens
),而且比其他任何解决方案都要快得多。