# Iterating Numpy Arrays

Nov 12, 2018 • 6 Minute Read

## 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.

` ````
A = np.arange(12)
for cell in A:
print(cell, end=' ')
```

Output:

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

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:

` ````
i = 0
while A[i] < A.size:
print(A[i])
i = i+1
if(i==A.size):
break
```

Output:

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

**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.

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

Output:

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

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

` ````
for row in A:
for cell in row:
print(cell, end=' ')
```

Output:

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

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:

` ````
for cell in A.flatten():
print(cell, end=' ')
```

Output:

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

## 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:

` ````
for cell in np.nditer(A):
print(cell, end=' ')
```

Output:

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

### 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.

For example, to get the ‘C’ order:

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

Output:

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

To get the Fortran order:

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

Output:

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

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:

` ``A`

Output:

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

And the transpose matrix ‘B’:

` ````
B = A.T
B
```

Output:

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

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

` ````
for cell in np.nditer(A):
print(cell, end=' ')
```

Output:

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

` ````
for x in np.nditer(B):
print(x, end=' ')
```

Output:

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

## 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.

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

Output:

` ``ValueError: assignment destination is read-only`

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

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

Output:

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

## 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:

` ````
S = np.arange(3)
S
```

Output:

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

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

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

Output:

` ````
0 0
2 1
4 2
6 0
8 1
10 2
…
```

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

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:

` ````
R = np.arange(4).reshape(4,1)
R
```

Output:

` ````
array([[0],
[1],
[2],
[3]])
```

` ``R.shape`

Output:

` ``(4, 1)`

` ````
for a,r in np.nditer([A,R]):
print(a, r)
```

Output:

` ````
0 0
2 0
4 0
6 1
8 1
...
```

This image summarizes the above operation:

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.