根据起始和结束位置列表构建Numpy索引

7 投票
4 回答
1982 浏览
提问于 2025-04-16 10:04

我有两个大小完全相同的一维数组(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),而且比其他任何解决方案都要快得多。

撰写回答