Array Concatenation, Splitting and Iteration Techniques in Numpy

Array Concatenation

Array concatenation involves combining multiple arrays along a specified axis to create a larger array. This operation allows you to merge arrays either horizontally (along columns) or vertically (along rows).

Let’s explore three key functions for array concatenation in NumPy:

np.concatenate()

The np.concatenate() is the main function for joining arrays in NumPy. It takes a sequence of arrays as input and concatenates them along the specified axis. For example, you can stack arrays vertically (like stacking blocks on top of each other) or horizontally (like placing blocks side by side). You can specify the axis using axis attribute.

Example:

import numpy as np

arr1=np.array([[3,8,4,6],[8,7,6,2]])
arr2=np.array([[4,2,2,1],[6,4,3,1]])

print("Join two arrays along rows :")
joint_arr1=np.concatenate((arr1,arr2), axis=0)
print(joint_arr1)

print("-----------------------")

print("Join two arrays along columns :")
joint_arr2=np.concatenate((arr1,arr2), axis=1)
print(joint_arr2)

Output :

Join two arrays along columns :
[[3 8 4 6]
 [8 7 6 2]
 [4 2 2 1]
 [6 4 3 1]]
-----------------------
Join two arrays along rows :
[[3 8 4 6 4 2 2 1]
 [8 7 6 2 6 4 3 1]]

np.vstack() & np.hstack()

If you only want to stack arrays vertically, np.vstack() is your go-to function. It’s like stacking plates one on top of the other. You don’t need to worry about the axis; it always stacks along rows. It is equivalent to np.concatenate() with axis=0.

When you need to stack arrays horizontally, use np.hstack(). It’s like placing plates side by side on a table. It is equivalent to np.concatenate() with axis=1.

Example: Stacking Arrays Horizontally

import numpy as np

# Two arrays with the same number of rows
array1 = np.array([[1, 2], [3, 4]])
array2 = np.array([[5, 6], [7, 8]])

# Horizontally concatenate them
concatenated_horizontal = np.hstack((array1, array2))

print("Array 1:")
print(array1)

print("\nArray 2:")
print(array2)

print("\nConcatenated Horizontally:")
print(concatenated_horizontal)

Output :

Array 1:
[[1 2]
 [3 4]]

Array 2:
[[5 6]
 [7 8]]

Concatenated Horizontally:
[[1 2 5 6]
 [3 4 7 8]]

Example: Stacking Arrays Vertically

import numpy as np

# Two arrays with the same number of columns
array3 = np.array([[7], [8]])
array4 = np.array([[9], [10]])
 
# Vertically concatenate them
concatenated_vertical = np.vstack((array3, array4))
 
print("Array 3:")
print(array3)
 
print("\nArray 4:")
print(array4)
 
print("\nConcatenated Vertically:")
print(concatenated_vertical)

Output :

Array 3:
[[7]
 [8]]

Array 4:
[[ 9]
 [10]]

Concatenated Vertically:
[[ 7]
 [ 8]
 [ 9]
 [10]]

Array Splitting

Array splitting in NumPy is a crucial operation for segmenting and organizing array data into manageable chunks. NumPy provides several functions for array splitting, let’s explore the 3 most used functions.

np.split()

The np.split() function divides an array into multiple sub-arrays along a specified axis. It takes three arguments: the array to split, the number of sections to split it into, and the axis along which to split. Here’s an example:

Example:

import numpy as np

# Create an array
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

# Split the array into three equal parts along axis 0
split_arr = np.split(arr, 3)

print(split_arr)

Output:

[array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9])]

np.hsplit()

If you need to split an array horizontally, you can use np.hsplit(). It divides a 2D array into smaller arrays along columns.

Example:

import numpy as np

# Create a 3x4 array
matrix = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

# Splitting the array horizontally into two equal subarrays
subarrays = np.hsplit(matrix, 2)

print("Original Array:")
print(matrix)

print("\nSplit Arrays Horizontally:")
for subarray in subarrays:
    print(subarray)

Output :

Original Array:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

Split Arrays Horizontally:
[[ 1  2]
 [ 5  6]
 [ 9 10]]
[[ 3  4]
 [ 7  8]
 [11 12]]

np.vsplit()

When you want to split an array vertically, you use np.vsplit(). It breaks a 2D array into smaller arrays along rows.

Example:

import numpy as np

# Create a 2D array
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 
# Splitting the array vertically into three subarrays
subarrays = np.vsplit(matrix, 3)
 
print("Original Array:")
print(matrix)
 
print("\nSplit Arrays Vertically:")
for subarray in subarrays:
    print(subarray)

Output :

Original Array:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Split Arrays Vertically:
[[1 2 3]]
[[4 5 6]]
[[7 8 9]]

Looping Through NumPy Arrays

Looping through arrays is a common task for accessing and working with the elements inside. This process is essential for performing calculations, applying functions, or extracting specific data points from arrays.

If you have a one-dimensional array, you can simply use a for loop to go through each element one by one. In addition, you can also use the list comprehension.

Example: Iterating through a 1D Array

import numpy as np
 
# Create a 1D array
array_1d = np.array([1, 2, 3, 4, 5])
 
# Using a for loop
for element in array_1d:
    print(element)
 
# Using a list comprehension
squared_elements = [x ** 2 for x in array_1d]
print("Squared Elements:", squared_elements)

Output :

1
2
3
4
5
Squared Elements: [1, 4, 9, 16, 25]

Iterate Multi-dimensional Arrays

When you’re dealing with arrays that have more than one dimension, like 2D arrays, you’ll use nested for loops. Each loop handles one dimension of the array. NumPy follows the row-major order for iteration, meaning it moves through the elements row by row. In a 2D array, it iterates through rows first and then columns.

Example 1: Iterating through a 2D Array

# Create a 2D array
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 
# Using nested loops
for row in matrix:
    for element in row:
        print(element)
 
# Using a list comprehension (flattening the array)
flattened_elements = [element for row in matrix for element in row]
print("Flattened Elements:", flattened_elements)

Output :

1
2
3
4
5
6
7
8
9
Flattened Elements: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Example 2: Iterating through a 3D Array

# Create a 3D array
cube = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
 
# Using nested loops for a 3D array
for layer in cube:
    for row in layer:
        for element in row:
        	print(element)
 
# Using a list comprehension (flattening the 3D array)
flattened_elements = [element for layer in cube for row in layer for element in row]
print("Flattened Elements:", flattened_elements)

Output :

1
2
3
4
5
6
7
8
Flattened Elements: [1, 2, 3, 4, 5, 6, 7, 8]

Using np.nditer() for Efficient Iteration

NumPy’s np.nditer() is a handy tool that helps you loop through arrays efficiently. Traditional loops in Python, such as for or while loops can be slow when applied to large arrays due to Python’s interpreted nature. In contrast, np.nditer() leverages optimized C code under the hood, resulting in significantly faster execution times, especially for large datasets.

With np.nditer(), you can perform complex operations on arrays with concise and readable code. It means you don’t have to write nested loops for multi-dimensional arrays.

Example:

import numpy as np
 
# Create a 2D array
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 
# Using numpy.nditer() with options
with np.nditer(matrix, flags=['multi_index'], op_flags=['readwrite'], order="F") as it:
    for x in it:
        print(f"Element at index {it.multi_index}: {x}")
 
# Performing operations during iteration
with np.nditer(matrix, op_flags=['readwrite']) as it:
    for x in it:
        # Square elements in the iterator
        it[0] = x ** 2
 
print("Squared Matrix:")
print(matrix)

In this example, we use np.nditer() to iterate through a 2D array, accessing elements and performing operations efficiently.

Output :

Element at index (0, 0): 1
Element at index (1, 0): 4
Element at index (2, 0): 7
Element at index (0, 1): 2
Element at index (1, 1): 5
Element at index (2, 1): 8
Element at index (0, 2): 3
Element at index (1, 2): 6
Element at index (2, 2): 9
Squared Matrix:
[[ 1  4  9]
 [16 25 36]
 [49 64 81]]

Understanding Key Parameters of np.nditer()

When using numpy.nditer(), you have several parameters to customize how the iteration process behaves. Let’s explore some of the key parameters available with np.nditer():

1. The op Option: This option tells np.nditer() which arrays to work with. You can specify one array or multiple arrays to iterate over.

2. Operand Data Types (op_dtypes): This option lets you specify the data types of the arrays you’re working with. You can choose one type or a sequence of types.

3. Order: Finally, the order option decides how the output array is laid out in memory:

  • "C": The array is stored in C-contiguous order, meaning it’s laid out row by row.
  • "F": The array is stored in Fortran-contiguous order, meaning it’s laid out column by column.
  • "A": It can be in either C or Fortran order.
  • "K": It keeps the existing order of the input array.

Flags Parameters

1. flags: Flags are like special instructions for the iteration process. Some mostly used flags are:

  • "c_index": It gives you the index of the current element, following C-order (like reading left to right, top to bottom).
  • "f_index": This one gives you the index of the current element, but in Fortran-order (like reading top to bottom, left to right).
  • "external_loop": Normally, np.nditer() returns one item at a time. This flag tells it to give you whole rows or columns instead.
  • "multi_index": Instead of just one index, this flag gives you a tuple of indices for the current element.
  • "ranged": You can limit the iteration to a specific range of elements.

2. Operand Flags (op_flags): These flags control how you can interact with the arrays you’re iterating over:

  • "readwrite": You can read from and write to the array.
  • "copy": It makes a copy of the array before iterating over it.
  • "no_broadcast": Prevents broadcasting, which is a way of stretching arrays to match each other’s shapes.
  • "readonly": You can only read from the array.
  • "writeonly": You can only write to the array.

Using np.ndenumerate() 

The np.ndenumerate() is a function in NumPy that iterates over elements of an array, providing both the index of each element and its corresponding value. This is particularly useful when you need to access both the value and its position within the array during iteration.

Using np.ndenumerate() is straightforward. Here’s a basic example demonstrating its usage:

Example:

import numpy as np
 
# Create a 2D array
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 
# Using numpy.ndenumerate()
for index, value in np.ndenumerate(matrix):
    print(f"Index {index}: Value {value}")

Output:

Index (0, 0): Value 1
Index (0, 1): Value 2
Index (0, 2): Value 3
Index (1, 0): Value 4
Index (1, 1): Value 5
Index (1, 2): Value 6
Index (2, 0): Value 7
Index (2, 1): Value 8
Index (2, 2): Value 9

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *