有没有办法在给定两组角索引坐标的情况下提取任意多维 Python 数组的实心框切片?

问题描述

假设我有 a = np.arange(16).reshape(4,4),即

array([[ 0,1,2,3],[ 4,5,6,7],[ 8,9,10,11],[12,13,14,15]])

我想用 aa[0:3,1:4] 进行切片,结果是

array([[ 1,[ 5,[ 9,11]])

使用提供的坐标 [(0,1),(2,3)],它们是该框切片角的索引。

我想创建一个函数,它接受任何 n 维数组和两组这样的索引坐标,并在这两个坐标之间对数组进行切片,包括两个坐标。 (可能是 Pythonic,我不会包括最后一个索引,所以前面提到的索引坐标应该是 [(0,(3,4)]。这个细节并不重要。)

示例:

import numpy as np

def Box_slice(array,start,stop):
    # will return slice
    pass

a = np.arange(3*5*6).reshape(3,6)

a 现在是

array([[[ 0,3,4,5],[ 6,7,8,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,2],[3,5])

输出

array([[[ 8,10],[14,16],[20,22]],[[38,40],[44,46],[50,52]],[[68,70],[74,76],[80,82]]])

这可以通过 eval() 实现,但我不想遵循这种方法,除非我必须这样做。是否已经有一个功能可以通过最少的输入操作来实现这一点?我更喜欢使用 NumPy,但也鼓励使用其他库或原始 Python 的解决方案。

解决方案需要支持任意数量的维度而无需修改

解决方法

我不确定这样做的方法是什么,但您可以使用 slicezip 来做到这一点。

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,1,2],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]]]