我想基于某些维度的索引位置数组提取numpy ndarray的部分。让我在的例子中展示一下
示例数据
dummy = np.random.rand(5,2,100)
X = np.array([[0,1],[4,1],[2,0]])
dummy
是维度为5x2x100的原始ndarray。这个维度是任意的,也可以是5x2x4x100。X
是索引值的矩阵,这里X[:,0]
是dummy
的第一维度的索引,X[:,1]
是第二维度的索引。X中的列数始终是dummy
中的维度数减去1。
示例输出
我想为这个例子提取以下形式的ndarray
[
dummy[0,1,:],
dummy[4,1,:],
dummy[2,0,:]
]
并发症
如果dummy
中的维度数量是固定的,那么这可以通过dummy[X[:,0],X[:,1],:]
来完成。遗憾的是,维度可能不同,例如,dummy
可能是5x2x4x6x100 ndarray,相应地,X
可能是3x4。我处理这一问题的努力没有取得预期的结果。
dummy[X,:]
在本例中产生了与dummy[X]
相同的3x2x100 ndarray- 通过对
i
执行类似于dummy = dummy[X[:,i],:]
的操作来迭代减少dummy
——在X
的列数上的迭代器也不会减少示例中超过3x2x100的ndarray
我有一种感觉,使用numpy索引应该很简单,但我想我在搜索解决方案时错过了正确的术语
有人能解决这个问题吗?
我将尝试为@Michael Szczesny的回答提供一些可解释性。
首先,请注意,如果您有一个维度为n
的np.array
,并在其中传递m<n
的m
索引,那么它将与在维度>=m
中使用:
相同。在您的情况下,例如:
dummy[(0, 0)] == dummy[0, 0, :]
鉴于此,请注意,您还可以将数组作为索引进行传递。因此:
dummy[([0, 1], [0, 0])]
它将与相同
np.array([dummy[(0,0)], dummy[(1,0)]])
您可以使用进行验证
dummy[([0, 1], [0, 0])] == np.array([dummy[(0,0)], dummy[(1,0)]])
最后,请注意:
(*X.T,)
# (array([0, 4, 2]), array([1, 1, 0]))
你在这里得到每个维度作为一个数组,然后你会得到:
[
dummy[0,1],
dummy[4,1],
dummy[2,0]
]
与相同
[
dummy[0,1,:],
dummy[4,1,:],
dummy[2,0,:]
]
编辑:您可以使用元组(X.T(,而不是使用(*X.T,(,这对我来说更有意义
正如Michael Szczesny所写,最好的解决方案是dummy[(*X.T,)]
。
由于X[:,0]
是dummy
的第一维度的索引,X[:,1]
是dummy
的第二维度的索引。如果将X
(X.T
(进行换位,则dummy
的第一维度索引将为X.T[0]
,dummy
的第二维索引将为X.T[1]
。
现在,要根据需要对dummy
进行切片,可以通过以下方式指定第一维度和第二维度的索引:
dummy[(first_dim_indices, second_dim_indices)] = dummy[(X.T[0], X.T[1])]
为了简化代码(并且由于您不想将X
矩阵转置两次(,您可以将元组中的X.T
解压缩为(*X.T,)
,因此编写X[(*X.T,)]
与编写dummy[(X.T[0], X.T[1])]
是一样的。
如果您有不固定数量的维度要通过槽进行切片,则这种编写也很有用,因为您将从X.T
中打开与dummy
中要切片的维度一样多的行。例如,假设您想从dummy
中检索一个1D数组,给定以下索引:
first_dim: (0, 4, 2)
second_dim: (1, 1, 0)
third_dim: (9, 8, 7)
您可以将3个维度的索引指定为X = np.array([[0,1,9],[4,1,8],[2,0,7]])
,并且dim[(*X.T,)]
仍然有效。