构造Numpy索引给出起始和结束位置的列表

时间:2011-01-16 19:44:43

标签: python 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 :(得分:4)

我会用

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),并且比其他任何解决方案都要快得多。

答案 1 :(得分: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]

答案 2 :(得分: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数组。

答案 3 :(得分:-1)

您说“或者您可以说我有一个起始位置和窗口长度列表”,这与您的示例数组不匹配。

如果start表示开始且end长度,则可以通过这种方式获取元素:

>>> [i for iter in [range(s,s+e) for s,e in zip(start,end)] for i in iter]
[1, 2, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 22, 23, 24, 25, 26, 
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]

如果你想匹配你的示例数组,而end实际上是结束元素-1 ,你可以这样得到你的元素:

>>> [i for iter in [range(*t) for t in zip(start,end)] for i in iter]
[1, 2, 7, 8, 9, 20, 21, 22, 23, 24]
>>> somearray=np.array(_)
>>> somearray
array([1, 2, 7, 8, 9, 20, 21, 22, 23, 24])

替代:

>>> sum([range(*t) for t in zip(start,end)],[])
[1, 2, 7, 8, 9, 20, 21, 22, 23, 24]

请记住,您只是生成元组中描述的整数列表作为numpy数组的索引。如果您的情况为faster / better,则其中任何一个都可以使用xrange vs range