Python 取锯齿状薄片的简写法

Python 取锯齿状薄片的简写法,python,arrays,numpy,indexing,array-broadcasting,Python,Arrays,Numpy,Indexing,Array 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 "e

我经常做一个手术,我称之为“锯齿形切片”,因为我不知道它的真实名称。最好用例子来解释:

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]),感兴趣的条目]
index(仅仅为了这个就必须构造“np.arange(a.shape[0])。我想要类似于
操作符的东西,但是
做了其他的事情。有没有更简洁的方法来做这个操作

最佳答案:
不,没有比这更好的办法了。如果需要,您可以为此创建一个帮助函数。

a的
锯齿片中的元素是
a[:,感兴趣的条目]的对角元素。

因此,一种稍微不那么麻烦的方法是使用提取它们

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

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

您也可以用于这种选择。这在语法上更清晰,但要想正确理解就更难了,而且可能更有限。此方法的等效值为:

entries_of_interest.choose(a.T)

这是combersome,只是因为它需要更多的打字来完成一项对你来说似乎很简单的任务

a[np.arange(a.shape[0]), entries_of_interest]
但正如您所注意到的,语法上更简单的
a[:,感兴趣的条目]
numpy
中有另一种解释。选择数组列的子集比从每行中选择一个(随机)项更常见

你的案子只是一个特殊的例子

a[I, J]
其中
I
J
是相同形状的两个数组。在一般情况下,感兴趣的
条目可以小于
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]

啊。不错,但它似乎是以为中间步骤构建巨大阵列为代价的。或者它只是一个视图?啊,你是对的-它确实创建了中间数组而不仅仅是一个视图,因此这种方法不是特别有效。我们在另一个so问题中发现,
choose
限制为32项,即
a.t.shape[0]
不能大于32项。e、 g.
N=32;np.arange(N).choose(np.arange(N*N).重塑(N,N))
Ah,我意识到
choose
有一些限制,但记不清它们是什么(我不经常使用)。我想这是因为
choose
是使用多维迭代器实现的,该迭代器限制了数组的维数。我以前没有注意到这一点,但是
choose
doc末尾有一个注释说,实际上,这个函数的使用是有效的,但这被认为是一种滥用<代码>选择
应该是一个序列,一个列表或元组,我也没有注意到其中的微妙之处。我猜
choose
主要用于简化小型数组上的多维奇特索引,或者用于需要使用
模式
kwarg修改索引/选择的情况。直截了当的花式索引仍然是像OP这样的案例的最佳解决方案。我认为它足够短,不需要在Ipython会话中测试就可以通过。:)