Pet*_*ter 5 python arrays indexing numpy 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 "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.
Run Code Online (Sandbox Code Playgroud)
唯一的问题是执行此a[np.arange(a.shape[0]), entries_of_interest]索引有点麻烦(为此而必须构造“np.arange(a.shape[0])”似乎很愚蠢)。我想要类似:操作员的东西,但它:会做其他事情。有没有更简洁的方法来执行此操作?
不,原生 numpy 没有更好的方法。如果需要,您可以为此创建一个辅助函数。
这很麻烦,只是因为它需要更多的输入来完成对您来说似乎很简单的任务。
a[np.arange(a.shape[0]), entries_of_interest]
Run Code Online (Sandbox Code Playgroud)
但正如您所注意到的,语法上更简单的a[:, entries_of_interest]在 中还有另一种解释numpy。选择数组列的子集是比从每行选择一个(随机)项目更常见的任务。
你的案例只是一个特殊的例子
a[I, J]
Run Code Online (Sandbox Code Playgroud)
其中I和J是两个形状相同的数组。在一般情况下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]
Run Code Online (Sandbox Code Playgroud)