【发布时间】:2016-05-03 03:34:37
【问题描述】:
import numpy as np
x = np.random.randn(2, 3, 4)
mask = np.array([1, 0, 1, 0], dtype=np.bool)
y = x[0, :, mask]
z = x[0, :, :][:, mask]
print(y)
print(z)
print(y.T)
为什么分两步做上面的操作会导致一步做的转置?
【问题讨论】:
import numpy as np
x = np.random.randn(2, 3, 4)
mask = np.array([1, 0, 1, 0], dtype=np.bool)
y = x[0, :, mask]
z = x[0, :, :][:, mask]
print(y)
print(z)
print(y.T)
为什么分两步做上面的操作会导致一步做的转置?
【问题讨论】:
以下是列表索引的相同行为:
In [87]: x=np.arange(2*3*4).reshape(2,3,4)
In [88]: x[0,:,[0,2]]
Out[88]:
array([[ 0, 4, 8],
[ 2, 6, 10]])
In [89]: x[0,:,:][:,[0,2]]
Out[89]:
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
在第二种情况下,x[0,:,:] 返回一个 (3,4) 数组,下一个索引选择 2 列。
在第一种情况下,它首先选择第一个和最后一个维度,并附加切片(中间维度)。 0 和 [0,2] 生成 2 维度,并附加中间的 3,给出 (2,3) 形状。
这是一个混合基本索引和高级索引的情况。
http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
在第一种情况下,高级索引操作产生的维度在结果数组中首先出现,然后是子空间维度。
这不是一个容易理解或解释的案例。基本上对于最终维度应该是什么存在一些歧义。它试图用一个例子来说明x[:,ind_1,:,ind_2],其中ind_1 和ind_2 是3d(或一起广播到那个)。
早期的解释是:
How does numpy order array slice indices?
Combining slicing and broadcasted indexing for multi-dimensional numpy arrays
============================
解决此问题的一种方法是将切片替换为数组 - 列向量
In [221]: x[0,np.array([0,1,2])[:,None],[0,2]]
Out[221]:
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
In [222]: np.ix_([0],[0,1,2],[0,2])
Out[222]:
(array([[[0]]]), array([[[0],
[1],
[2]]]), array([[[0, 2]]]))
In [223]: x[np.ix_([0],[0,1,2],[0,2])]
Out[223]:
array([[[ 0, 2],
[ 4, 6],
[ 8, 10]]])
虽然最后一种情况是 3d, (1,3,2)。 ix_ 不喜欢标量 0。使用 ix_ 的另一种方式:
In [224]: i,j=np.ix_([0,1,2],[0,2])
In [225]: x[0,i,j]
Out[225]:
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
这是一种获取相同数字的方法,但在 (2,1,3) 数组中:
In [232]: i,j=np.ix_([0,2],[0])
In [233]: x[j,:,i]
Out[233]:
array([[[ 0, 4, 8]],
[[ 2, 6, 10]]])
【讨论】: