In the last article, we have learned about Numpy module in Python and also have seen the concept of N-Dimensional Array with examples. It is now time to see some more useful Numpy functions. This time we will focus on another two important functions - `reshape()`

and `nditer()`

. Both of the functions are widely used by Python Programmers and Developers across all the platforms and hence it is important to understand the usage of these functions with the help of examples. More on Numpy official documentation.

**Useful Numpy Functions: reshape() and nditer()**

**reshape()** -> Numpy `reshape()`

function shapes an array without modifying the actual elements of array. Like, 1D array can be shaped into any other dimensional array and vice-versa. Let's understand by following example.

**Example**

```
import numpy
array = numpy.arange(1, 9, 1)
print(f"1D Array : {array}")
t_array = array.reshape(4, 2)
print(f"Reshaped in 2D-Array:\n {t_array}")
m_array = array.reshape(2,2,2)
print(f"Reshaped in 3D-Array:\n {m_array}")
```

**Output**

```
1D Array : [1 2 3 4 5 6 7 8]
Reshaped in 2D-Array:
[[1 2]
[3 4]
[5 6]
[7 8]]
Reshaped in 3D-Array:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
```

Similarly, an array can be reshaped into any dimension. Just make sure the number of elements in an array to be reshaped is equal in both shapes. Like, in above example, 8 element of 1D-array can be reshaped into 4 rows of 2 elements but it can't be reshaped into 3 rows of 3 elements as it would require 9 elements in 1D-array.

Multi-dimensional array can also be converted back into 1D-array by passing -1 as value to the function `reshape()`

.

**Example**

```
import numpy
array = numpy.array([[1,2], [3,4], [5,6]])
print(f"2D-Array:\n{array}")
print(f"Converted 1D-Array: \n {array.reshape(-1)}")
```

**Output**

```
Actual Array:
[[1 2]
[3 4]
[5 6]]
1D-Array:
[1 2 3 4 5 6]
```

**nditer()** -> `numpy.nditer`

is an iterator object provided by python Numpy package. It is used to iterate over an array in efficient and organized manner. Let's define and iterate an array using below example to understand the concept. There are 3 orders in which iteration can be performed. By default the order is 'K' which matches the memory layout of defined array without considering any particular order. Other 2 orders are 'C' and 'F'. There comes time when iteration needs to be done in a particular order without considering memory layout of defined array. In such cases, an extra parameter is passed to the `nditer()`

function to provide the order of iteration.

**Example1: Using Default Order**

```
import numpy
array = numpy.arange(1, 10)
m_array = array.reshape(3, 3)
print(f"Actual Array:\n{array}")
print(f"Reshaped Array:\n{m_array}")
print("Iterated Array:\n")
for i in numpy.nditer(m_array):
print(i)
```

**Output**

```
Actual Array:
[1 2 3 4 5 6 7 8 9]
Reshaped Array:
[[1 2 3]
[4 5 6]
[7 8 9]]
Iterated Array:
1 2 3 4 5 6 7 8 9
```

**Example 2: Using 'C' Order**

```
import numpy
array = numpy.arange(1, 10)
m_array = array.reshape(3, 3)
print(f"Actual Array:\n{array}")
print(f"Reshaped Array:\n{m_array}")
print("Iterated Array:\n")
for i in numpy.nditer(m_array, order = 'C'):
print(i)
```

**Output**

```
Actual Array:
[1 2 3 4 5 6 7 8 9]
Reshaped Array:
[[1 2 3]
[4 5 6]
[7 8 9]]
Iterated Array:
1 2 3 4 5 6 7 8 9
```

**Example 3: Using 'F' Order**

```
import numpy
array = numpy.arange(1, 10)
m_array = array.reshape(3, 3)
print(f"Actual Array:\n{array}")
print(f"Reshaped Array:\n{m_array}")
print("Iterated Array:\n")
for i in numpy.nditer(m_array, order = 'F'):
print(i)
```

**Output**

```
Actual Array:
[1 2 3 4 5 6 7 8 9]
Reshaped Array:
[[1 2 3]
[4 5 6]
[7 8 9]]
Iterated Array:
1 4 7 2 5 8 3 6 9
```