采取锯齿状切片的numpy简写

时间:2015-11-16 12:58:40

标签: python arrays numpy indexing numpy-broadcasting

我有一个我正常做的操作,我称之为“锯齿状切片”,因为我不知道它的真实名称。最好用例子解释:

a = np.random.randn(50, 10)
entries_of_interest = np.random.randint(10, size = 50)  # Vector of 50 indices between 0 and 9
# Now I want the values contained in each row of a at the corresponding index in "entries of interest"
jagged_slice_of_a = a[np.arange(a.shape[0]), entries_of_interest]
# jagged_slice_of_a is now a vector with 50 elements.  Good.

唯一的问题是这样做a[np.arange(a.shape[0]), entries_of_interest]索引有点麻烦(为了这个而必须构造“np.arange(a.shape [0])”似乎很愚蠢)。我想要:运算符之类的东西,但:会做其他事情。有没有更简洁的方法来做这个操作?

最佳答案:

不,没有更好的方式与原生numpy。如果需要,可以为此创建辅助函数。

3 个答案:

答案 0 :(得分:3)

我认为你当前的方法可能是最好的方法。

您也可以使用choose进行此类选择。这在语法上更清晰,但更难以正确,可能更有限。与此方法等效的是:

entries_of_interest.choose(a.T)

答案 1 :(得分:1)

jagged_slice_of_a中的元素是a[:,entries_of_interest]

的对角元素

这样做稍微麻烦的方法就是使用np.diagonal来提取它们。

jagged_slice_of_a = a[:, entries_of_interest].diagonal()

答案 2 :(得分:1)

这仅仅是因为它需要为你看起来很简单的任务进行更多的打字,所以这是精简版。

a[np.arange(a.shape[0]), entries_of_interest]

但是正如您所注意到的,语法更简单的a[:, entries_of_interest]numpy中有另一种解释。选择数组列的子集是一项更常见的任务,即从每行中选择一个(随机)项。

您的案例只是

的专门实例
a[I, J]

其中IJ是2个相同形状的数组。在一般情况下,entries_of_interest可能小于a.shape[0](不是所有行)或更大(某些行中的几个项目),甚至可能是2d。它甚至可以反复选择某些元素。

我在其他SO问题中发现,当应用于a.flat时,执行此类元素选择会更快。但这需要一些数学来构造I*n+J种扁平指数。

凭借您对J的特殊了解,构建I似乎是额外的工作,但numpy无法做出这种假设。如果这种选择更常见,那么有人可以编写一个包装表达式的函数

def  peter_selection(a,I):
   # check the a.shape[0]==I.shape[0]
   return a[np.arange(a.shape[0]), I]