在数组边界上切片ndarray

时间:2018-02-07 08:32:58

标签: python numpy numpy-slicing

问题:

给出了一个ndarray:

In [2]: a
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

我寻找一个例行公事给我:

array([7, 8, 9, 0, 1])

E x。:从索引8开始,越过数组边界并在索引2处停止(包括) 如果我使用切片,我(当然)得到:

In [3]: a[-3:2]
Out[3]: array([], dtype=int64)

一个可能的答案:

是否使用滚动功能。

In [5]: np.roll(a,3)[:5]
Out[5]: array([7, 8, 9, 0, 1])

我在找什么:

我不喜欢这个,它不像切片那么简单。所以我寻找类似的东西:

In [6]: a.xxx[-3:2]

例如pandas.DataFrame.iloc中存在类似于此语法的语法。非常感谢你提前!

注意:iloc,没有做我想要的。我只是提到了语法(我喜欢)。感谢您的评论,cᴏʟᴅsᴘᴇᴇᴅ

3 个答案:

答案 0 :(得分:3)

python / numpy中没有任何切片机制自动包装列表/数组(作为循环容器),因为你似乎正在寻找,所以真正唯一的方法就是使用函数。您使用roll所做的事情很好而且紧凑,即使它不像您喜欢的那样惯用。下面,我概述了几个(略多)惯用/ pythonic解决方案,它们做同样的事情。

选项1
np.take基于hpaulj's comment

np.take(a, range(len(a) - 3, len(a) + 2), mode='wrap')
array([7, 8, 9, 0, 1])

选项2
islice cycle个对象:

from itertools import islice, cycle

list(islice(cycle(a), len(a) - 3, len(a) + 2))
[7, 8, 9, 0, 1] 

答案 1 :(得分:1)

不像coldspeeds解决方案或滚动那么漂亮,但

def over_edge_slicing(arr, start, end):
    return np.append(arr[start:], arr[:end])

a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(over_edge_slicing(a, -3, 2))

是写这个的另一种方式。但是,你失去了一般性(你不能用它来从索引2-4切片)。

答案 2 :(得分:0)

使用np.arange()

问这个问题 3 年后,我突然想到了这个......

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[np.arange(-3, 2)]
array([7, 8, 9, 0, 1])