有没有办法在给定两组角索引坐标的情况下提取任意多维 Python 数组的实心框切片?
Is there a way to extract a solid box slice of an arbitrary multidimensional Python array given two sets of corner index coordinates?
假设我有a = np.arange(16).reshape(4,4)
,也就是
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
并且想像 a[0:3,1:4]
那样分割 a
,结果是
array([[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11]])
使用提供的坐标 [(0,1), (2,3)],它们是该框切片角的索引。
我想创建一个函数,它接受任何 n 维数组和两组索引坐标,并在这两个坐标之间对数组进行切片,包括这两个坐标。
(可能是 Pythonic,我不会包括最后一个索引,所以前面提到的索引坐标将是 [(0,1), (3,4)]。这个细节并不重要。)
一个例子:
import numpy as np
def box_slice(array, start, stop):
# will return slice
pass
a = np.arange(3*5*6).reshape(3,5,6)
a
现在是
array([[[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29]],
[[30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41],
[42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53],
[54, 55, 56, 57, 58, 59]],
[[60, 61, 62, 63, 64, 65],
[66, 67, 68, 69, 70, 71],
[72, 73, 74, 75, 76, 77],
[78, 79, 80, 81, 82, 83],
[84, 85, 86, 87, 88, 89]]])
这应该等同于 a[0:3, 1:4, 2:5]
,假设 Pythonic 实现:
box_slice(a, [0,1,2], [3,4,5])
输出:
array([[[ 8, 9, 10],
[14, 15, 16],
[20, 21, 22]],
[[38, 39, 40],
[44, 45, 46],
[50, 51, 52]],
[[68, 69, 70],
[74, 75, 76],
[80, 81, 82]]])
这可以通过 eval()
实现,但除非万不得已,否则我不想采用这种方法。是否已经有一个函数可以通过对输入进行最少的操作来实现这一点?我更喜欢使用 NumPy,但也鼓励使用其他库或原始 Python 的解决方案。
解决方案无需修改即可支持任意数量的维度。
我不确定这样做的 numpy 方式,但您可以使用 slice
和 zip
来做到这一点。
import numpy as np
def box_slice(arr, start, stop):
return arr[tuple(slice(*i) for i in zip(start, stop))]
a = np.arange(16).reshape(4, 4)
print(box_slice(a, [0, 1], [3, 4]))
a = np.arange(3 * 5 * 6).reshape(3, 5, 6)
print(box_slice(a, [0, 1, 2], [3, 4, 5]))
输出
[[ 1 2 3]
[ 5 6 7]
[ 9 10 11]]
[[[ 8 9 10]
[14 15 16]
[20 21 22]]
[[38 39 40]
[44 45 46]
[50 51 52]]
[[68 69 70]
[74 75 76]
[80 81 82]]]
假设我有a = np.arange(16).reshape(4,4)
,也就是
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
并且想像 a[0:3,1:4]
那样分割 a
,结果是
array([[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11]])
使用提供的坐标 [(0,1), (2,3)],它们是该框切片角的索引。
我想创建一个函数,它接受任何 n 维数组和两组索引坐标,并在这两个坐标之间对数组进行切片,包括这两个坐标。 (可能是 Pythonic,我不会包括最后一个索引,所以前面提到的索引坐标将是 [(0,1), (3,4)]。这个细节并不重要。)
一个例子:
import numpy as np
def box_slice(array, start, stop):
# will return slice
pass
a = np.arange(3*5*6).reshape(3,5,6)
a
现在是
array([[[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29]],
[[30, 31, 32, 33, 34, 35],
[36, 37, 38, 39, 40, 41],
[42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53],
[54, 55, 56, 57, 58, 59]],
[[60, 61, 62, 63, 64, 65],
[66, 67, 68, 69, 70, 71],
[72, 73, 74, 75, 76, 77],
[78, 79, 80, 81, 82, 83],
[84, 85, 86, 87, 88, 89]]])
这应该等同于 a[0:3, 1:4, 2:5]
,假设 Pythonic 实现:
box_slice(a, [0,1,2], [3,4,5])
输出:
array([[[ 8, 9, 10],
[14, 15, 16],
[20, 21, 22]],
[[38, 39, 40],
[44, 45, 46],
[50, 51, 52]],
[[68, 69, 70],
[74, 75, 76],
[80, 81, 82]]])
这可以通过 eval()
实现,但除非万不得已,否则我不想采用这种方法。是否已经有一个函数可以通过对输入进行最少的操作来实现这一点?我更喜欢使用 NumPy,但也鼓励使用其他库或原始 Python 的解决方案。
解决方案无需修改即可支持任意数量的维度。
我不确定这样做的 numpy 方式,但您可以使用 slice
和 zip
来做到这一点。
import numpy as np
def box_slice(arr, start, stop):
return arr[tuple(slice(*i) for i in zip(start, stop))]
a = np.arange(16).reshape(4, 4)
print(box_slice(a, [0, 1], [3, 4]))
a = np.arange(3 * 5 * 6).reshape(3, 5, 6)
print(box_slice(a, [0, 1, 2], [3, 4, 5]))
输出
[[ 1 2 3]
[ 5 6 7]
[ 9 10 11]]
[[[ 8 9 10]
[14 15 16]
[20 21 22]]
[[38 39 40]
[44 45 46]
[50 51 52]]
[[68 69 70]
[74 75 76]
[80 81 82]]]