2

I have a 3d matrix of shape (7,4,6) where 4x6 is (rows x columns) and 7 is the number of frames/layers. I want to iterate each layer over each values in 4x6. However the loop always gives an index error if I change the order of loop from (frames, rows, columns) to (rows, columns, frames). The code I used is:

>>> array.shape
(7, 4, 6)
>>> for i in range(0,4):
...     for j in range(0,6):
...         for k in range(0,7):
...             print(array[i][j][k])

I want the frames to be the innermost loop but I get an index error when I run the above code. Any suggestions on how can I modify the above code?

4
  • 2
    First the 0 is redundant. you can simply write in range(4),range(5) and range(7). Second, I think the order need to be 7,4,6 and not what you wrote Commented Mar 18, 2020 at 8:01
  • In addition to the answer below, you can use np.ravel to "flatten" the array to 1D. Commented Mar 18, 2020 at 8:26
  • ^ or array.flatten() itself. Commented Mar 18, 2020 at 8:51
  • You should use not use so many brackets. Instead use print(array[k ,i ,j]) because it is more readable and faster. Commented Jan 21, 2022 at 14:19

3 Answers 3

1

numpy has a function for this: np.nditer:

>>> array = np.random.randint(0, 10, size = (3,4,5))
>>> array.shape
(3, 4, 5)
>>> array
array([[[8, 8, 0, 6, 0],
        [9, 4, 6, 6, 1],
        [4, 3, 1, 3, 6],
        [2, 4, 4, 3, 9]],

       [[3, 5, 3, 9, 6],
        [8, 0, 8, 5, 3],
        [4, 8, 6, 2, 7],
        [2, 7, 1, 8, 4]],

       [[5, 7, 5, 6, 7],
        [7, 4, 2, 7, 0],
        [5, 6, 7, 9, 7],
        [7, 2, 7, 7, 4]]])
>>> for elem in np.nditer(array):
...     print(elem, end=' ')

8 8 0 6 0 9 4 6 6 1 4 3 1 3 6 2 4 4 3 9 3 5 3 9 6 8 0 8 5 3 4 8 6 2 7 2 7 1 8 4 5 7 5 6 7 7 4 2 7 0 5 6 7 9 7 7 2 7 7 4 

If you want to print them in different order, use the order flag:

>>> for idx in np.nditer(array, order='F'):
...     print(idx, end = ' ')
8 3 5 9 8 7 4 4 5 2 2 7 8 5 7 4 0 4 3 8 6 4 7 2 0 3 5 6 8 2 1 6 7 4 1 7 6 9 6 6 5 7 3 2 9 3 8 7 0 6 7 1 3 0 6 7 7 9 4 4

If you want the indices, you can use np.ndindex:

>>> for idx in np.ndindex(array.shape):
...     print(array[idx], end=' ')
8 8 0 6 0 9 4 6 6 1 4 3 1 3 6 2 4 4 3 9 3 5 3 9 6 8 0 8 5 3 4 8 6 2 7 2 7 1 8 4 5 7 5 6 7 7 4 2 7 0 5 6 7 9 7 7 2 7 7 4 

np.ndindex gives indices as tuples:

>>> for idx in np.ndindex(array.shape):
...     print(idx, end=' ')
(0, 0, 0) (0, 0, 1) (0, 0, 2) (0, 0, 3) (0, 0, 4) (0, 1, 0) (0, 1, 1) (0, 1, 2) (0, 1, 3) (0, 1, 4) (0, 2, 0) (0, 2, 1) (0, 2, 2) (0, 2, 3) (0, 2, 4) (0, 3, 0) (0, 3, 1) (0, 3, 2) (0, 3, 3) (0, 3, 4) (1, 0, 0) (1, 0, 1) (1, 0, 2) (1, 0, 3) (1, 0, 4) (1, 1, 0) (1, 1, 1) (1, 1, 2) (1, 1, 3) (1, 1, 4) (1, 2, 0) (1, 2, 1) (1, 2, 2) (1, 2, 3) (1, 2, 4) (1, 3, 0) (1, 3, 1) (1, 3, 2) (1, 3, 3) (1, 3, 4) (2, 0, 0) (2, 0, 1) (2, 0, 2) (2, 0, 3) (2, 0, 4) (2, 1, 0) (2, 1, 1) (2, 1, 2) (2, 1, 3) (2, 1, 4) (2, 2, 0) (2, 2, 1) (2, 2, 2) (2, 2, 3) (2, 2, 4) (2, 3, 0) (2, 3, 1) (2, 3, 2) (2, 3, 3) (2, 3, 4)
Sign up to request clarification or add additional context in comments.

2 Comments

HI Sayandip, thank you for the suggestion. All i had to was change the order flag to get my required order:)
@rohitnarayanan glad it helped. You may consider marking it as accepted if you think it answers your question :)
1

You should use the following:

>>> array.shape
(7, 4, 6)
>>> for j in range(4):
...     for k in range(6):
...         for i in range(7):
...            print(array[i][j][k])

You are using the wrong indexers in your original code.

Comments

0

A more elegant and pythonic way of doing that could be using itertools module.

from itertools import product

def using_itertools(array):
    X, Y, Z = array.shape
    for x, y, z in product(range(X), range(Y), range(Z)):
        print(array[x,y,z])

def using_forloop(array):
    X, Y, Z = array.shape
    for k in range(Z):
        for j in range(Y):
            for i in range(X):
                print(array[i][j][k])

Although the first approach looks clean, speed-wise I found both to be similar.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.