Author avatar

Ravikiran Srinivasulu

Iterating Numpy Arrays

Ravikiran Srinivasulu

  • Nov 12, 2018
  • 6 Min read
  • 13,666 Views
  • Nov 12, 2018
  • 6 Min read
  • 13,666 Views
Numpy
Python

Introduction

This guide will introduce you to the basics of NumPy array iteration. We will also have a deep dive into the iterator object nditer and the powerful iteration capabilities it offers.

Iterating NumPy Arrays

First, let’s look at iterating NumPy arrays without using the nditer object.

Iterating a One-dimensional Array

Iterating a one-dimensional array is simple with the use of For loop.

1
2
3
A = np.arange(12)
for cell in A:
    print(cell, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11
python

The end specifies the character that needs to be printed after printing the value. By default, it prints a new line character.

Similar to the programming languages like C# and Java, you can also use a while loop to iterate the elements in an array. For example:

1
2
3
4
5
6
i = 0
while A[i] < A.size:
    print(A[i])
    i = i+1
    if(i==A.size):
        break
python

Output:

1
2
3
4
5
6
7
8
9
10
11
12
0
1
2
3
4
5
6
7
8
9
10
11
python

A.size returns the number of elements in the array. Note the indented block after : for while loop and the if statement that is required to pass the syntax check.

Iterating a Two-dimensional Array

If you use the same syntax to iterate a two-dimensional array, you will only be able to iterate a row.

1
2
3
A = np.arange(12).reshape(4,3)
for row in A:
    print(row)
python

Output:

1
2
3
4
[0 1 2]
[3 4 5]
[6 7 8]
[ 9 10 11]
python

To iterate each cell in the two-dimensional array, nest the for loop.

1
2
3
for row in A:
    for cell in row:
        print(cell, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11
python

If you do not want to write two for loops, you can use the flatten function that flattens the two-dimensional array into a one-dimensional array. For example:

1
2
for cell in A.flatten():
        print(cell, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11
python

A Look at the Nditer Object

NumPy provides a multi-dimensional iterator object called nditer to iterate the elements of an array. For example, you can use nditer in the previous example as:

1
2
for cell in np.nditer(A):
    print(cell, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11
python

Nditer Iteration Order

You can control how the elements are accessed with nditer using the order parameter. If you specify the order as C then C order is followed, which is traversing the elements in the array horizontally. If you specify the order as F, the Fortran order is followed which is traversing the elements in the array vertically.

memoryorder

For example, to get the ‘C’ order:

1
2
for cell in np.nditer(A, order='C'):
    print(cell, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11
python

To get the Fortran order:

1
2
for cell in np.nditer(A, order='F'):
    print(cell, end=' ')
python

Output:

1
0 3 6 9 1 4 7 10 2 5 8 11
python

By default, nditer follows the order ‘k’ which means that it follows an order to match the memory layout of the array. This default setting allows it to access the elements in the least possible time. To prove that, let’s define a matrix ‘B’ as the transpose of the two-dimensional matrix ‘A.’ So we have:

1
A
python

Output:

1
2
3
4
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])
python

And the transpose matrix ‘B’:

1
2
B = A.T
B
python

Output:

1
2
3
array([[ 0,  3,  6,  9],
       [ 1,  4,  7, 10],
       [ 2,  5,  8, 11]])
python

So, if we iterate with the default order ‘k,’ we should see the same output for both the matrices ‘A’ and ‘B’.

1
2
for cell in np.nditer(A):
    print(cell, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11
python
1
2
for x in np.nditer(B):
    print(x, end=' ')
python

Output:

1
0 1 2 3 4 5 6 7 8 9 10 11 
python

Modifying NumPy Arrays

Nditer treats the elements of the array as read-only. So, if you try to modify the values, you will run into an error.

1
2
for cell in np.nditer(A):
    cell[...] =cell*2
python

Output:

1
ValueError: assignment destination is read-only
python

To modify the array while you iterate, use the op_flags parameter. So, to update the elements of the array:

1
2
3
for cell in np.nditer(A, op_flags=['readwrite']):
    cell[...] =cell*2
A
python

Output:

1
2
3
4
array([[ 0,  2,  4],
       [ 6,  8, 10],
       [12, 14, 16],
       [18, 20, 22]])
python

Iterating Two Arrays Simultaneously

To iterate two arrays simultaneously, pass two arrays to the nditer object. Then you have array ‘A,’ a four by three two-dimensional array and an array ‘S,’ a one-dimensional array object:

1
2
S = np.arange(3)
S
python

Output:

1
array([0, 1, 2])
python

So, to iterate the arrays ‘A’ and ‘S’ simultaneously:

1
2
for a,s in np.nditer([A,S]):
    print(a, s)
python

Output:

1
2
3
4
5
6
7
0 0
2 1
4 2
6 0
8 1
10 2
python

This image summarizes how the iteration works across two arrays, ‘A’ and ‘S’:

matrixS

If you would like to have a constant value from the matrix ‘S’ for each element in a row in the array ‘A,’ then use the following matrix ‘R’ with shape four by one:

1
2
R = np.arange(4).reshape(4,1)
R
python

Output:

1
2
3
4
array([[0],
       [1],
       [2],
       [3]])
python
1
R.shape
python

Output:

1
(4, 1)
python
1
2
for a,r in np.nditer([A,R]):
    print(a, r)
python

Output:

1
2
3
4
5
6
0 0
2 0
4 0
6 1
8 1
...
python

This image summarizes the above operation:

matrixR

Note that both the arrays need to follow the broadcasting rules if you need to iterate simultaneously on two different arrays. Review my previous guide on broadcasting in NumPy: Broadcasting NumPy Arrays for Arithmetic Operations.

Conclusion

The nditer iterator object provides a systematic way to touch each of the elements of the array. This guide only gets you started with tools to iterate a NumPy array. In addition to the capabilities discussed in this guide, you can also perform more advanced iteration operations like Reduction Iteration, Outer Product Iteration, etc.

23