# NumPy shape and reshape

## NumPy shape ndarray

The shape of an array(NumPy ndarray) represents the number of items in each dimension. We can get the shape of the array using the shape attribute. The shape attribute returns a tuple with each index representing the number of corresponding items.

For example,
```import numpy as np
nums = np.array([[10, 20, 30],[40, 50, 60],[70, 80, 90]])
#2-D array
print(nums.shape) #(3, 3)

#3-D array
zeros=np.empty([3,2,3])
zeros.fill(0)
print(zeros.shape) #(3, 2, 3)

```

We can also create an array with ndmin option in array function.
```import numpy as np
#3-D array
nums = np.array([[1,2,3,3],[4,4,2,3]], ndmin=3)
print(nums.shape) #(1, 2, 4)
```
OR

```import numpy as np
#5-D array
nums = np.array([1,2,3,3,5], ndmin=5)
print(nums.shape) #(1, 1, 1, 1, 5)
```

## Numpy Reshape

We can reshape an array using the reshape function. We can add or modify dimensions or change the number of items in each dimension by reshaping the ndarray.

In the example below, we have converted a 1-D array into 2-D and 3-D array.
```import numpy as np
#1-D array
nums = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120])
#2-D array
nums2d = nums.reshape(3, 4)
print(nums2d)
print()
#3-D array
nums3d = nums.reshape(2, 2, 3)
print(nums3d)

#Output
[[ 10  20  30  40]
[ 50  60  70  80]
[ 90 100 110 120]]

[[[ 10  20  30]
[ 40  50  60]]

[[ 70  80  90]
[100 110 120]]]
```
We also need to take the number of the dimensions carefully for reshaping, if the number of elements in the original array does not match the number of elements in the expected array then it will raise an error.

## Unknown Dimension

We can also provide have one dimension as unkown. It means that we do not need to provide an exact number for one of the dimensions in the reshape method. We can just pass -1 (to specify unknown), and NumPy will automatically find this number for you, but we can not pass -1 for more than one dimension.

```import numpy as np
#1-D array
nums = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120])
#3-D array
nums2d = nums.reshape(2, 2, -1)
print(nums2d.shape) #(2, 2, 3)
```

## Flattening the array

We can also change a multidimensional array into a 1-D array using flattening by using reshape(-1).

```import numpy as np
#2-D array
nums = np.array([[10, 20, 30],[ 40, 50, 60], [70, 80, 90], [100, 110, 120]])
#flattening
nums1d = nums.reshape(-1)
print(nums1d) #1-D array

#Output
[ 10  20  30  40  50  60  70  80  90 100 110 120]
```