a_new = a.transpose(0, 2, 1).reshape(N*L, M, order="F")
extra_column = np.repeat(np.arange(L), N)
b = np.column_stack((a_new, extra_column))
We first swap the last 2 axes of a with transpose and then reshape it to desired shape but with Fortran order to match the output. Extra column is produced with repeated np.arange(L) and added with column_stack.
Sample run:
>>> N, M, L = 6, 3 ,5
>>> a = np.arange(N*M*L).reshape(N, M, L)
>>> # above operations...
>>> b
array([[ 0, 5, 10, 0],
[15, 20, 25, 0],
[30, 35, 40, 0],
[45, 50, 55, 0],
[60, 65, 70, 0],
[75, 80, 85, 0],
[ 1, 6, 11, 1],
[16, 21, 26, 1],
[31, 36, 41, 1],
[46, 51, 56, 1],
[61, 66, 71, 1],
[76, 81, 86, 1],
[ 2, 7, 12, 2],
[17, 22, 27, 2],
[32, 37, 42, 2],
[47, 52, 57, 2],
[62, 67, 72, 2],
[77, 82, 87, 2],
[ 3, 8, 13, 3],
[18, 23, 28, 3],
[33, 38, 43, 3],
[48, 53, 58, 3],
[63, 68, 73, 3],
[78, 83, 88, 3],
[ 4, 9, 14, 4],
[19, 24, 29, 4],
[34, 39, 44, 4],
[49, 54, 59, 4],
[64, 69, 74, 4],
[79, 84, 89, 4]])