Method 1 :
import numpy as np
from skimage.util import view_as_blocks
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# Define block shape
block_shape = (2, 2)
# Slice the array into blocks
blocks = view_as_blocks(arr, block_shape)
print(blocks)
'''
[[[[1 2]
[5 6]]
[[3 4]
[7 8]]]]
'''
Method 2(concise) :
import numpy as np
from numpy.lib.stride_tricks import as_strided
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# Block size
block_shape = (2, 2)
a_shape = np.array(a.shape)
print(a_shape)#[2 4]
#convert the arrays to lists
new_shape = (a_shape // block_shape).tolist() + list(block_shape)
print(new_shape)#[1,2,2, 2]
new_strides = (a.strides[0] * block_shape[0], a.strides[1] * block_shape[1]) + a.strides
print(new_strides)
res = as_strided(a, shape = new_shape, strides = new_strides)
print(res)
'''
[[[[1 2]
[5 6]]
[[3 4]
[7 8]]]]
'''
Method 2 :
import numpy as np
from numpy.lib.stride_tricks import as_strided
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
# Block size
block_shape = (2, 2)
shape = a.shape
strides = a.strides
newShape1 =( shape[0] // block_shape[0] )
newShape2 =( shape[1] // block_shape[1] )
newShape = (newShape1,newShape2,block_shape[0],block_shape[1])
print(newShape)#(1, 2, 2, 2)
newStrides1 = strides[0] * block_shape[0]
newStrides2 = strides[1] * block_shape[1]
newStrides = (newStrides1, newStrides2,strides[0],strides[1] )
print(newStrides) #(32, 8, 16, 4)
blocks = as_strided(a, shape = newShape, strides = newStrides)
print(blocks)
'''
[[[[1 2]
[5 6]]
[[3 4]
[7 8]]]]
'''
Einsum :
import numpy as np
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# Define block shape
block_shape = (2, 2)
grsize = 4
halfsize = grsize // 2
reshaped = a.reshape(-1, grsize)
aa = np.einsum('ij -> ij', reshaped[:, :halfsize])
bb = np.einsum('ij -> ij', reshaped[:, halfsize:])
# Stack aa and bb along a new axis
combined = np.stack([aa, bb], axis=0)
print(combined)
'''
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
'''
# Reshape to the desired 4D shape
final_output = combined.reshape(1, 2, 2, 2)
print(final_output)
'''
[[[[1 2]
[5 6]]
[[3 4]
[7 8]]]]
'''
tensordot :
import numpy as np
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# Define block shape
block_shape = (2, 2)
grsize = 4
halfsize = grsize // 2
reshaped = a.reshape(-1, grsize)
# Split the reshaped array into two halves using tensordot
aa = np.tensordot(a[:, :halfsize], np.ones((1,), dtype=int), axes=0)
bb = np.tensordot(a[:, halfsize:], np.ones((1,), dtype=int), axes=0)
# Stack aa and bb along a new axis
combined = np.stack([aa, bb], axis=0)
print(combined)
# Reshape to the desired 4D shape
final_output = combined.reshape(1, 2, 2, 2)
print(final_output)
'''
[[[[1 2]
[5 6]]
[[3 4]
[7 8]]]]
'''
Method 5 :
import numpy as np
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# Block size
block_shape = (2, 2)
blockVertical = a.shape[0] // block_shape[0]
blockHorizontal = a.shape[0] // blockVertical
reshapedArray1 = a.reshape(blockVertical,blockHorizontal,*block_shape).swapaxes(1,2)
print(reshapedArray1)
'''
[[[[1 2]
[5 6]]
[[3 4]
[7 8]]]]
'''