Understanding NumPy Array Shapes in Python
Tags: python, numpy, array, analytics
Published: 2024-05-22 06:58:26

Common Operations for Reshaping or Resizing of NumPy Array Shapes

|Function/Method |Description
|----------------:|--------------|
|`reshape()`	|Returns a new array with a specified shape, without modifying the original data.
|`flat()`	|Provides an iterator that flattens the array and allows access to the array elements using an index.
|`flatten()`	|Returns a one-dimensional copy of the array, effectively flattening it.
|`ravel()`	|Returns a one-dimensional view of the array, which is a flattened version that shares data with the original array.
|`transpose()`	|Transposes the axes of the array, effectively flipping the dimensions.
|`resize()`	|Similar to reshape(), but it modifies the original array to the new shape.

---

#### <u>RESHAPE:</u>

In many programming languages, including Python with libraries like NumPy, there's a function called reshape() that allows you to change the shape of an array without changing its data. This is particularly useful when you need to manipulate the structure of your data without altering its content.

Here's how it works:

1. Input: You start with an array of a certain shape.
2. Reshaping: You apply the reshape() function to that array, specifying the new shape you want.
3. Output: The function returns a new array with the specified shape, while keeping the original data intact.
Here's an example in Python using NumPy:

```python
import numpy as np

# Create a 1D array with 12 elements
arr = np.arange(12)
print("Original array:")
print(arr)

# Reshape the array into a 3x4 array
reshaped_arr = arr.reshape(3, 4)
print("\nReshaped array:")
print(reshaped_arr)
```

```python
Original array:
[ 0  1  2  3  4  5  6  7  8  9 10 11]

Reshaped array:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
```
In this example, arr.reshape(3, 4) reshapes the original 1D array into a 3x4 array. Notice that the reshaped array contains the same data as the original array, but now it's organized in a 3x4 grid. The reshape() function returns a new array with the specified shape, leaving the original array unchanged.

---
#### <u>FLAT:</u>
The `flat` attribute of a NumPy array returns an iterator that helps in accessing the array as if it were a flat (1D) array. It doesn't actually flatten the array; rather, it allows you to access the elements as though they were in a flattened array.

Here's an example to illustrate how `flat` works:

```python
import numpy as np

# Creating a 2D array
array = np.array([[10, 20, 30], [40, 50, 60]])

# Accessing elements using the flat attribute
print("Element at index 3:", array.flat[3])
```

```python
Element at index 3: 40
```
In the above code:
- We create a 2D array with the shape `(2, 3)`.
- We use `array.flat[3]` to access the fourth element as if the array was flattened. The index `3` corresponds to the element `40` because the flattened array would look like `[10, 20, 30, 40, 50, 60]`, and indexing starts at `0`.

Remember, `flat` is an attribute, not a method, so you don't call it with parentheses. It provides a view on the array elements in a 1D fashion without actually changing the array structure.

---
#### <u>FLATTEN:</u>
The flatten() function in NumPy is used to create a one-dimensional copy of a multi-dimensional array. Here's an example to illustrate this concept in Python:

```python
import numpy as np

# Create a two-dimensional array
arr = np.array([[1, 2, 3],
                [4, 5, 6]])

# Use flatten() to create a one-dimensional copy
flattened_arr = arr.flatten()

print("Original array:")
print(arr)
print("\nFlattened array:")
print(flattened_arr)
```

```python
Original array:
[[1 2 3]
 [4 5 6]]

Flattened array:
[1 2 3 4 5 6]
```
As you can see, the arr array is a two-dimensional array with two rows and three columns. The flatten() function collapses this array into a one-dimensional array, flattened_arr, which contains all the elements of the original array in row-major order (i.e., elements from the first row followed by elements from the second row, and so on).

It's important to remember that flatten() creates a copy of the original array. So, any modifications made to the flattened_arr array won't affect the data array, and vice versa.

---
#### <u>RAVEL:</u>
The `numpy.ravel()` function in Python's NumPy library is used to create a contiguous flattened 1D array from a multi-dimensional input array. It returns a view of the original array whenever possible. 

Here's an example to illustrate how `ravel()` works:

```python
import numpy as np

# Let's create a 2D numpy array
array_2d = np.array([[1, 2, 3], [4, 5, 6]])

# Now, we use ravel() to flatten this array
flattened_array = np.ravel(array_2d)

print(flattened_array)
```

Output:
```
[1 2 3 4 5 6]
```

In this example, `array_2d` is a 2D array with two rows and three columns. When we apply `np.ravel(array_2d)`, it flattens the array into a 1D array by unrolling the elements row-wise (which is the default 'C' order). The result is a new array `flattened_array` that contains all the elements of `array_2d`, but in a single, flat structure.

The `ravel()` function can also take an `order` parameter, which allows you to specify the way elements are read from the array:
- `'C'` - row-major order (default)
- `'F'` - column-major order (Fortran-style)
- `'A'` - Fortran-like order if the array is Fortran contiguous in memory, C-like order otherwise
- `'K'` - read the elements in the order they occur in memory, except for reversing the data when strides are negative.

For instance, if you want to flatten the array in column-major order, you would do:

```python
flattened_array_F = np.ravel(array_2d, order='F')
print(flattened_array_F)
```

Output:
```
[1 4 2 5 3 6]
```

Here, the elements are unrolled column-wise, starting from the first column and moving to the next, which is why the output sequence is different from the default order.

---
#### <u>TRANSPOSE:</u>
The numpy.transpose() function in Python’s NumPy library is used to swap or permute the axes of a given array. It’s similar to taking the transpose of a matrix in mathematics. 
######Let’s dive into an example and explain how it works:

```python
import numpy as np

# Example 1: Transposing a 2D array
original_array = np.array([[1, 2], [3, 4]])
transposed_array = np.transpose(original_array)
print("Original array:")
print(original_array)
print("Transposed array:")
print(transposed_array)

# Example 2: Transposing a 1D array (returns the original array)
one_d_array = np.array([1, 2, 3, 4])
transposed_one_d_array = np.transpose(one_d_array)
print("Original 1D array:")
print(one_d_array)
print("Transposed 1D array (same as original):")
print(transposed_one_d_array)
```

```python
Example:1
Original array:
[[1 2]
 [3 4]]
Transposed array:
[[1 3]
 [2 4]]
Example:2
Original 1D array:
[1 2 3 4]
Transposed 1D array (same as original):
[1 2 3 4]
```
In Example 1, we transpose a 2D array by swapping rows and columns. The resulting transposed array has elements rearranged.
Example 2 shows that transposing a 1D array returns the same array since there’s only one dimension.

---
##### <u>RESIZE:</u>
The `resize()` method is used to **modify the shape of an array in-place**. It can be called either as a function or as a method of the array object. Here's how it works:

1. **Using `resize()` as a method (in-place modification):**
   - When you call `resize()` as a method on an existing array, it modifies that array directly.
   - The original array is changed to the specified shape, and if the new shape requires more elements, the array is filled with repeated values.
   - If the new shape has fewer elements, the array is truncated.
   - The modified array is returned, but you can also access it directly from the original array.

2. **Using `resize()` as a function (returns a new array):**
   - If you call `np.resize(arr, new_shape)`, it returns a new array with the specified shape.
   - The new array contains elements from the original array, repeated or truncated as needed.
   - The original array remains unchanged.

Let's see an example:

```python
import numpy as np

# Original array
original_array = np.array([1, 2, 3, 4, 5, 6])

# Using resize as a method (in-place modification)
original_array.resize((2, 3))
print("Original Array after resize (in-place):\n", original_array)

# Using resize as a function (returns a new array)
new_resized_array = np.resize(original_array, (3, 2))
print("New Resized Array (returned by resize function):\n", new_resized_array)

# Original array remains unchanged
print("Original Array after resize (still in-place):\n", original_array)
```

Output:
```
Original Array after resize (in-place):
 [[1 2]
 [3 4]
 [5 6]]
New Resized Array (returned by resize function):
 [[1 2]
 [3 4]
 [5 6]]
Original Array after resize (still in-place):
 [[1 2]
 [3 4]
 [5 6]]
```

In this example:
- The original array is resized in-place to a shape of `(2, 3)`.
- We also create a new resized array using the `np.resize()` function with a shape of `(3, 2)`.

Remember that `resize()` modifies the original array, while `reshape()` returns a new array without changing the original. Choose the method that suits your needs based on whether you want in-place modification or a new array. 😊