我有一个多维np.array
。我知道前N维和后M维的形状。例如,
>>> n = (3,4,5)
>>> m = (6,)
>>> a = np.ones(n + m)
>>> a.shape
(3, 4, 5, 6)
字符串
使用元组作为索引可以快速索引前N个维度,如
>>> i = (1,1,2)
>>> a[i].shape
(6,)
型
使用列表并不能给予我所需要的结果
>>> i = [1,1,2]
>>> a[i].shape
(3, 4, 5, 6)
型
但是我在做多索引(既检索又赋值)时遇到了麻烦。例如,
>>> i = (1,1,2)
>>> j = (2,2,2)
型
我需要通过一些东西,
>>> a[[i, j]]
型
并得到(2, 6)
的输出形状。
但我却得到了
>>> a[[i, j]].shape
(2, 3, 4, 5, 6)
型
或
>>> a[(i, j)].shape
(3, 5, 6)
型
我总是可以循环或改变我索引的方式(比如使用np.reshape
和np.unravel_index
),但是有没有更pythonic的方法来实现我所需要的?
EDIT我需要任何数量的索引,例如,
>>> i = (1,1,2)
>>> j = (2,2,2)
>>> k = (0,0,0)
...
型
4条答案
按热度按时间ruarlubt1#
考虑一个索引列表:
字符串
和形状为
(3, 4, 5, 6)
的数组a
。当你写
out = a[idx]
时,numpy会这样解释:型
其中,例如
a[0]
,只是a
的第一个子阵列,因此具有形状(4, 5, 6)
!结果,你得到的是一个形状为
(5, 3)
的数组(索引的形状),包含a
!的(4, 5, 6)
子数组(......最终结果是(5, 3, 4, 5, 6)
或np.shape(idx) + a.shape[1:]
)。相反,您想要的是以下内容:
型
在numpy中实现“矢量化”的方法如下:
型
该行为记录在索引指南中:
高级索引始终作为一个索引广播和迭代:
型
要将原始
idx
转换为这样的索引器,可以使用tuple(zip(*idx))
技巧。Numpy的索引系统非常灵活,但这种灵活性的代价是这些“简单”的任务变得不直观......至少在我看来;)
djmepvbi2#
提取每个选择,然后将它们重新组合成一个新的数组?
字符串
zlwx9yxi3#
我测试了ShadowRanger和Adulphylaxs的解决方案,并将它们与我最初的解进行了比较。我对它们进行了计时,Adulphylaxs的是最快的。
个字符
7kjnsjlb4#
让我们学究气,以澄清发生了什么,在每一个案件。
字符串
加上元组(以及列表和字符串)加入它们:
型
使用元组索引与单独输入每个标量是一样的。是逗号组成了元组,而不是()。实际上是解释器将元组传递给对象;它是对象自己的
getitem
方法来解释它。(如果你给列表给予一个元组,列表会抱怨,但数组喜欢它:))。型
有一个自动跟踪切片。在下面我将包括这一点,以明确(呃):
型
[i,j]
被转换为数组,(2,3)形状:型
所以这个数组只用于索引第一维。其余的都是跟踪。
型
元组的元组:
型
内部元组被转换为列表,或者更确切地说,转换为数组。因此,两个索引一起广播,选择一个(3,)形状(将其视为“对角线”)
型
加上
k
,a[i,j,k]
将得到给予(3,6)形状。我不知道你的
i,j
应该如何产生(2,6)形状等等,也许这相当于
型
或者等效地用
np.array
连接两个选择。就像experiment一样,这里有一个等价物:
型
所以我们需要将
i,j
元组转换为这个pairs元组。型
用第三个元组
型
我们不需要
tolist
,尽管它相当快:型