For a comprehensive introcution of NumPy, refer to:

**Basic Concept of Reshaping**

Think of reshaping as changing the arrangement of items in an array. The total number of items (or chocolates in our analogy) remains the same.

**Basic Reshaping Techniques**

`reshape()`

method

`reshape()`

methodThis is your go-to method for reshaping.

Let’s say you have a 1D array and want to make it 2D:

```
one_d_array = np.array([1, 2, 3, 4, 5, 6])
two_d_array = one_d_array.reshape(2, 3)
print(two_d_array)
# Outputs
# [[1 2 3]
# [4 5 6]]
```

`2`

: The number of rows in the reshaped array.`3`

: The number of columns in the reshaped array.

** Understanding **`reshape()`

`reshape()`

- The first argument (2) is the number of rows.
- The second argument (3) is the number of columns.

**The **`-1`

trick

`-1`

trickIf you’re unsure about a dimension size, use `-1`

, and NumPy will figure it out for you.

```
two_d_array = np.array([[1, 2, 3], [4, 5, 6]])
two_d_array = one_d_array.reshape(2, -1)
print(two_d_array)
# Outputs
# [[1 2 3]
# [4 5 6]]
```

It lets NumPy automatically calculate the size of that dimension.

**Flattening Arrays**

Sometimes, you’ll want to turn a multi-dimensional array back into a 1D array. This process is called flattening.

**Using **`ravel()`

`ravel()`

It returns a flattened array.

```
two_d_array = np.array([[1, 2, 3], [4, 5, 6]])
flattened_array = two_d_array.ravel()
print(flattened_array) # Outputs [1 2 3 4 5 6]
```

**Understanding **`ravel()`

`ravel()`

It doesn’t create a new array but gives a view of the original array. This means changes in the flattened array can affect the original.

**Difference between **`ravel()`

and `flatten()`

`ravel()`

and `flatten()`

While both methods flatten an array, `flatten()`

returns a new array, ensuring the original remains unchanged.

**Transposing Arrays**

Ever wanted to swap rows with columns? That’s what transposing does!

**Using the **`T`

attribute

`T`

attributeIt’s a quick way to transpose a matrix.

```
array = np.array([[1, 2], [3, 4], [5, 6]])
transposed = array.T
print(transposed)
# Outputs
# [[1 3 5]
# [2 4 6]]
```

**Understanding **`T`

`T`

- It swaps rows and columns.
- No new array is created; it’s just a different view of the original array.

**Reshaping with More Dimensions**

While 2D arrays (matrices) are common, NumPy supports arrays with many dimensions. Let’s explore!

**Creating a 3D array**

`three_d_array = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])`

**Understanding 3D arrays**

- Think of it as a stack of matrices.
- The above example has 2 matrices, each of size 2×2.

**Reshaping to 3D**

```
array = np.array([1, 2, 3, 4, 5, 6, 7, 8])
reshaped_to_3d = array.reshape(2, 2, 2)
print(reshaped_to_3d)
# Outputs
# [[[1 2]
# [3 4]]
# [[5 6]
# [7 8]]]
```

**Understanding **`reshape(2, 2, 2)`

`reshape(2, 2, 2)`

It creates 2 matrices, each of size 2×2.

**Changing Dimensions with **`newaxis`

`newaxis`

Sometimes, you might want to add a new dimension to your array, like converting a 1D array to a column or row matrix.

**Using **`newaxis`

for column matrix

`newaxis`

for column matrix```
array = np.array([1, 2, 3, 4])
column_matrix = array[:, np.newaxis]
print(column_matrix)
# Outputs
# [[1]
# [2]
# [3]
# [4]]
```

In this context, the colon `:`

is a slicing operator in NumPy. It means “select all elements along this axis.”

**Understanding **`[:, np.newaxis]`

`[:, np.newaxis]`

It adds a new axis, converting the 1D array to a 2D column matrix.

**Using **`newaxis`

for row matrix

`newaxis`

for row matrix```
array = np.array([1, 2, 3, 4])
row_matrix = array[np.newaxis, :]
print(row_matrix)
# Outputs [[1 2 3 4]]
```

** Understanding **`[np.newaxis, :]`

`[np.newaxis, :]`

It adds a new axis, converting the 1D array to a 2D row matrix.

**Understanding Order in Reshaping**

When reshaping or flattening, the order in which data is read can be crucial.

**Using the **`order`

parameter

`order`

parameter```
array = np.array([[1, 2], [3, 4], [5, 6]])
reshaped = array.reshape(2, 3, order='F')
print(reshaped)
# Outputs
# [[1 5 4]
# [3 2 6]]
```

`2`

: The number of rows in the reshaped array.`3`

: The number of columns in the reshaped array.

When you reshape with `order='F'`

, it reads the array column by column:

- First column: 1, 3, 5
- Second column: 2, 4, 6

Now, when placing these values into the new 2×3 shape:

- First row takes the first two values from the first column (1, 3), and the first value from the second column (2).
- Second row takes the last value from the first column (5), and the last two values from the second column (4, 6).

**Understanding **`order='F'`

`order='F'`

order=’f’ specifies the order in which the elements are read from the original array and placed into the reshaped array.

The value `'F'`

stands for Fortran-like index order, which means column-major order. In this order, elements from the original array are read column by column (as opposed to row by row in the default C-like order).

- Data is read column-wise (Fortran-like).
- Default is
`order='C'`

, which reads data row-wise (C-like).

**Resizing Arrays**

Unlike reshaping, resizing changes the size of the array. If the new size is larger, the array is repeated; if smaller, it’s truncated.

**Using the **`resize()`

method

`resize()`

method```
array = np.array([1, 2, 3, 4])
resized = np.resize(array, (2, 3))
print(resized)
# Outputs
# [[1 2 3]
# [4 1 2]]
```

`2`

: The number of rows in the resized array.`3`

: The number of columns in the resized array.

**Understanding **`resize()`

`resize()`

- It returns a new array with the specified shape.
- If the new size is larger, the original array is repeated.