【发布时间】:2019-10-13 04:06:30
【问题描述】:
考虑以下几点:
import numpy as np
arr = np.arange(3 * 4 * 5).reshape((3, 4, 5))
如果我使用slices 切片arr,我会得到,例如:
arr[:, 0:2, :].shape
# (3, 2, 5)
如果现在我使用slice() 和tuple() 的混合物对arr 进行切片,我得到:
arr[:, (0, 1), :].shape
# (3, 2, 5)
np.all(arr[:, (0, 1), :] == arr[:, :2, :])
# True
和:
arr[:, :, (0, 1)].shape
# (3, 4, 2)
np.all(arr[:, :, (0, 1)] == arr[:, :, :2])
# True
但是,如果我这样做:
arr[:, (0, 1), (0, 1)].shape
# (3, 2)
基本上,arr[:, 0, 0] 和 arr[:, 1, 1] 串联。
我期待得到:
arr[:, (0, 1), (0, 1)].shape
# (3, 2, 2)
np.all(arr[:, (0, 1), (0, 1)] == arr[:, :2, :2])
# True
但显然不是这样的。
如果我连接两个单独的切片,我将能够获得所需的结果,即:
arr[:, (0, 1), :][:, :, (0, 1)].shape
# (3, 2, 2)
np.all(arr[:, (0, 1), :][:, :, (0, 1)] == arr[:, :2, :2])
# True
是否有可能获得与arr[:, (0, 1), :][:, :, (0, 1)] 相同的结果,但使用单个切片?
现在,这个例子没那么有趣了,因为我可以用 slice() 替换 tuple(),但如果不是这样,这一切都会变得更加相关,例如:
arr[:, (0, 2, 3), :][:, :, (0, 2, 3, 4)]
# [[[ 0 2 3 4]
# [10 12 13 14]
# [15 17 18 19]]
# [[20 22 23 24]
# [30 32 33 34]
# [35 37 38 39]]
# [[40 42 43 44]
# [50 52 53 54]
# [55 57 58 59]]]
arr[:, (0, 2, 3), (0, 2, 3, 4)] 的语法会更方便。
编辑
@Divakar @hpaulj 和 @MadPhysicist cmets / answers 指向正确广播的 Iterable 等效于多个连接切片。
但是,情况并非如此,例如:
s = np.ix_((0, 1), (0, 1, 2, 3))
arr[s[0], slice(3), s[1]]
# [[[ 0 5 10]
# [ 1 6 11]
# [ 2 7 12]
# [ 3 8 13]]
#
# [[20 25 30]
# [21 26 31]
# [22 27 32]
# [23 28 33]]]
但是:
arr[(0, 1), :, :][:, :3, :][:, :, (0, 1, 2, 3)]
# [[[ 0 1 2 3]
# [ 5 6 7 8]
# [10 11 12 13]]
#
# [[20 21 22 23]
# [25 26 27 28]
# [30 31 32 33]]]
和:
np.all(arr[:2, :3, :4] == arr[(0, 1), :, :][:, :3, :][:, :, (0, 1, 2, 3)])
# True
np.all(arr[s[0], slice(3), s[1]] == arr[(0, 1), :, :][:, :3, :][:, :, (0, 1, 2, 3)])
# False
【问题讨论】:
-
与
np.ix_-x,y = np.ix_([0,2,3],[0,2,3,4]); arr[:,x,y]。或arr[:,np.array([0,2,3])[:,None],[0,2,3,4]]. -
您期待 MATLAB 风格的索引块。但是要获取元素,例如 MATLAB 中的对角线,您必须使用
sub2ind将下标转换为平面索引。实际上,在 MATLAB 中简单的事情在numpy中(只是)稍微复杂一点,反之亦然。 -
@hpaulj 这与多个串联切片的工作方式不同,而且我看不到让它在单个切片中工作的方法。
-
将切片放在中间会引发 doxs 中描述的维度顺序问题。 stackoverflow.com/q/55829631/901925
-
我需要对此进行测试以确定,但我认为 slice 可以被 ix_ 参数中的另一个元组或 arange 替换。
标签: python numpy array-broadcasting numpy-slicing