如何沿给定的轴取其索引指定的元素? [英] How to take elements along a given axis, given by their indices?
问题描述
我有一个3D数组,我需要在最后一个轴上挤压"它,以便获得2D数组.我需要按以下方式进行操作.对于前两个维度的每个索引值,我知道第三个维度的索引值应从何处取值.
I have a 3D array and I need to "squeeze" it over the last axis, so that I get a 2D array. I need to do it in the following way. For each values of the indices for the first two dimensions I know the value of the index for the 3rd dimension from where the value should be taken.
例如,我知道如果i1 == 2
和i2 == 7
然后是i3 == 11
.这表示out[2,7] = inp[2,7,11]
.从前两个维到第三个维的映射在另一个2D数组中给出.换句话说,我有一个数组,其中在位置2,7
上我有11
作为值.
For example, I know that if i1 == 2
and i2 == 7
then i3 == 11
. It means that out[2,7] = inp[2,7,11]
. This mapping from first two dimensions into the third one is given in another 2D array. In other words, I have an array in which on the position 2,7
I have 11
as a value.
所以,我的问题是如何组合这两个数组(3D和2D)以获得输出数组(2D).
So, my question is how to combine these two array (3D and 2D) to get the output array (2D).
推荐答案
In [635]: arr = np.arange(24).reshape(2,3,4)
In [636]: idx = np.array([[1,2,3],[0,1,2]])
In [637]: I,J = np.ogrid[:2,:3]
In [638]: arr[I,J,idx]
Out[638]:
array([[ 1, 6, 11],
[12, 17, 22]])
In [639]: arr
Out[639]:
array([[[ 0, 1, 2, 3], # 1
[ 4, 5, 6, 7], # 6
[ 8, 9, 10, 11]], # ll
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
I,J
一起广播以选择一组(2,3)值,这些值与idx
相匹配:
I,J
broadcast together to select a (2,3) set of values, matching idx
:
In [640]: I
Out[640]:
array([[0],
[1]])
In [641]: J
Out[641]: array([[0, 1, 2]])
这是对更简单的2d问题的3d的概括-从每一行中选择一项:
This is a generalization to 3d of the easier 2d problem - selecting one item from each row:
In [649]: idx
Out[649]:
array([[1, 2, 3],
[0, 1, 2]])
In [650]: idx[np.arange(2), [0,1]]
Out[650]: array([1, 1])
实际上,我们可以将3d问题转换为2d问题:
In fact we could convert the 3d problem into a 2d one:
In [655]: arr.reshape(6,4)[np.arange(6), idx.ravel()]
Out[655]: array([ 1, 6, 11, 12, 17, 22])
概括原始案例:
Generalizing the original case:
In [55]: arr = np.arange(24).reshape(2,3,4)
In [56]: idx = np.array([[1,2,3],[0,1,2]])
In [57]: IJ = np.ogrid[[slice(i) for i in idx.shape]]
In [58]: IJ
Out[58]:
[array([[0],
[1]]), array([[0, 1, 2]])]
In [59]: (*IJ,idx)
Out[59]:
(array([[0],
[1]]), array([[0, 1, 2]]), array([[1, 2, 3],
[0, 1, 2]]))
In [60]: arr[_]
Out[60]:
array([[ 1, 6, 11],
[12, 17, 22]])
关键在于将数组的IJ
列表与idx
组合在一起以创建新的索引元组.如果idx
不是最后一个索引,则构造元组会有点麻烦,但是仍然可能.例如
The key is in combining the IJ
list of arrays with the idx
to make a new indexing tuple. Constructing the tuple is a little messier if idx
isn't the last index, but it's still possible. E.g.
In [61]: (*IJ[:-1],idx,IJ[-1])
Out[61]:
(array([[0],
[1]]), array([[1, 2, 3],
[0, 1, 2]]), array([[0, 1, 2]]))
In [62]: arr.transpose(0,2,1)[_]
Out[62]:
array([[ 1, 6, 11],
[12, 17, 22]])
如果更容易将arr
换位为idx
维度,则为最后.关键是索引操作采用索引数组的元组,索引数组相互广播以选择特定项.
这就是ogrid
的工作,创建与idx
一起使用的数组.
Of if it's easier transpose arr
to the idx
dimension is last. The key is that the index operation takes a tuple of index arrays, arrays which broadcast against each other to select specific items.
That's what ogrid
is doing, create the arrays that work with idx
.
这篇关于如何沿给定的轴取其索引指定的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!