¿Cómo dividir una matriz numpy en trozos de tamaño fijo con y sin superposición?

Digamos que tengo una matriz:

>>> arr = np.array(range(9)).reshape(3, 3) >>> arr array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) 

Me gustaría crear una función f(arr, shape=(2, 2)) que tome la matriz y una forma, y ​​la divida en partes de la forma dada sin relleno. Por lo tanto, mediante la superposición de ciertas partes si es necesario. Por ejemplo:

 >>> f(arr, shape=(2, 2)) array([[[[0, 1], [3, 4]], [[1, 2], [4, 5]]], [[[3, 4], [6, 7]], [[4, 5], [7, 8]]]]) 

np.lib.stride_tricks.as_strided(arr, shape=(2, 2, 2, 2), strides=(24, 8, 24, 8)) crear en la salida anterior con np.lib.stride_tricks.as_strided(arr, shape=(2, 2, 2, 2), strides=(24, 8, 24, 8)) . Pero no sé cómo generalizar esto para todas las matrices y todos los tamaños de trozos.

Preferiblemente, para matrices 3D.

Si no es necesario superponer, debe evitar eso. Otro ejemplo:

 >>> arr = np.array(range(16).reshape(4,4) >>> arr array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) >>> f(arr, shape=(2,2)) array([[[[0, 1], [4, 5]], [[2, 3], [6, 7]]], [[[8, 9], [12, 13]], [[10, 11], [14, 15]]]]) 

skimage.util.view_as_blocks se acerca, pero requiere que la matriz y la forma del bloque sean compatibles.

Hay una incorporada en scikit-image como view_as_windows para hacer exactamente eso –

 from skimage.util.shape import view_as_windows view_as_windows(arr, (2,2)) 

Ejecución de la muestra

 In [40]: arr Out[40]: array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) In [41]: view_as_windows(arr, (2,2)) Out[41]: array([[[[0, 1], [3, 4]], [[1, 2], [4, 5]]], [[[3, 4], [6, 7]], [[4, 5], [7, 8]]]]) 

Para la segunda parte, use su primo de la misma familia / módulo view_as_blocks

 from skimage.util.shape import view_as_blocks view_as_blocks(arr, (2,2))