Python | Numpy Arrays | SORTING

 Python | Numpy Arrays  | SORTING 




Adding, Removing, and Sorting Elements in NumPy Arrays

A Complete Beginner-to-Advanced Guide to np.sort() and np.concatenate()

NumPy is one of the most important Python libraries for numerical computing. When working with arrays, we frequently need to:

  • Sort elements

  • Combine multiple arrays

  • Add data to an existing array

  • Remove unwanted elements

  • Arrange multidimensional data along a particular axis

  • Find the positions of elements after sorting

  • Perform partial or multi-key sorting

NumPy provides several powerful functions for these operations.

In this article, we will focus primarily on:

np.sort()
np.concatenate()

We will also briefly explore related sorting functions:

np.argsort()
np.lexsort()
np.searchsorted()
np.partition()

1. Prerequisites

Before working with these functions, import NumPy:

import numpy as np

You can verify the installed version with:

print(np.__version__)

Example:

import numpy as np

print(np.__version__)

Possible output:

2.3.2

The exact version depends on your NumPy installation.


2. Understanding NumPy Arrays

Before sorting or combining arrays, let's understand the basic structure of a NumPy array.

Create a one-dimensional array:

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

print(arr)

Output:

[2 1 5 3 7 4 6 8]

Here:

  • np is the conventional alias for NumPy.

  • array() creates a NumPy array.

  • [2, 1, 5, 3, 7, 4, 6, 8] is the input sequence.

The array has:

Number of dimensions = 1
Number of elements   = 8

You can check these properties:

print(arr.ndim)
print(arr.size)
print(arr.shape)

Output:

1
8
(8,)

3. Sorting an Array Using np.sort()

Sorting means arranging elements in a particular order.

For numbers, the most common order is ascending order.

Consider:

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

Sort it using:

sorted_arr = np.sort(arr)

print(sorted_arr)

Output:

[1 2 3 4 5 6 7 8]

The original array remains unchanged:

print(arr)

Output:

[2 1 5 3 7 4 6 8]

This is an important characteristic of np.sort().

Key Point

np.sort() returns a sorted copy of the array.

It does not normally modify the original array.


4. Syntax of np.sort()

The general syntax is:

numpy.sort(a, axis=-1, kind=None, order=None)

Since we normally import NumPy as np, we write:

np.sort(a, axis=-1, kind=None, order=None)

Let's understand every parameter.


5. a Parameter

The first parameter is the array that needs to be sorted.

Example:

arr = np.array([5, 2, 8, 1, 3])

result = np.sort(arr)

print(result)

Output:

[1 2 3 5 8]

Here:

a = arr

6. axis Parameter

The axis parameter determines along which dimension sorting should happen.

This becomes particularly important for multidimensional arrays.

For a one-dimensional array:

arr = np.array([5, 3, 8, 1, 6])

print(np.sort(arr))

Output:

[1 3 5 6 8]

For a 2-D array:

arr = np.array([
    [5, 2, 8],
    [9, 1, 6]
])

The array looks like:

5  2  8
9  1  6

Its shape is:

print(arr.shape)

Output:

(2, 3)

There are:

  • 2 rows

  • 3 columns


7. Sorting Along axis=1

Use:

np.sort(arr, axis=1)

Example:

arr = np.array([
    [5, 2, 8],
    [9, 1, 6]
])

result = np.sort(arr, axis=1)

print(result)

Output:

[[2 5 8]
 [1 6 9]]

Each row is sorted independently.

Original:

5 2 8
9 1 6

After sorting:

2 5 8
1 6 9

Therefore:

axis=1

means sorting across the columns within each row.


8. Sorting Along axis=0

Now consider:

result = np.sort(arr, axis=0)

print(result)

Output:

[[5 1 6]
 [9 2 8]]

The values in each column are sorted independently.

Original:

5 2 8
9 1 6

Column-wise sorting:

5 1 6
9 2 8

Therefore:

axis=0

sorts along the rows, meaning each column is sorted independently.


9. Understanding axis=-1

The default value is:

axis=-1

-1 means the last axis.

For a 2-D array:

axis=0 → rows
axis=1 → columns
axis=-1 → last axis → axis=1

Therefore:

np.sort(arr)

for a 2-D array generally sorts each row because the default axis is the last axis.

Example:

arr = np.array([
    [8, 2, 5],
    [4, 9, 1]
])

print(np.sort(arr))

Output:

[[2 5 8]
 [1 4 9]]

10. Sorting in Descending Order

A common question is:

Can np.sort() directly sort numbers in descending order?

np.sort() sorts numerical values in ascending order by default.

One simple technique is:

arr = np.array([5, 2, 8, 1, 9])

result = np.sort(arr)[::-1]

print(result)

Output:

[9 8 5 2 1]

Let's understand:

np.sort(arr)

produces:

[1 2 5 8 9]

Then:

[::-1]

reverses the array:

[9 8 5 2 1]

11. Sorting Strings

np.sort() can also sort strings.

Example:

names = np.array([
    "Ravi",
    "Anita",
    "Kiran",
    "Bhavya"
])

print(np.sort(names))

Output:

['Anita' 'Bhavya' 'Kiran' 'Ravi']

The strings are sorted lexicographically.


12. Sorting Floating-Point Numbers

Example:

marks = np.array([78.5, 92.3, 65.7, 88.1, 70.4])

print(np.sort(marks))

Output:

[65.7 70.4 78.5 88.1 92.3]

13. Sorting an Array Without Changing the Original

Consider:

arr = np.array([50, 10, 30, 20, 40])

sorted_arr = np.sort(arr)

print("Original:", arr)
print("Sorted:", sorted_arr)

Output:

Original: [50 10 30 20 40]
Sorted: [10 20 30 40 50]

This is useful when you need to preserve the original ordering.


14. np.sort() vs array.sort()

NumPy provides two related approaches.

Using np.sort()

result = np.sort(arr)

This returns a sorted copy.

Using the array method

arr.sort()

This sorts the array in place.

Example:

arr = np.array([5, 2, 8, 1])

arr.sort()

print(arr)

Output:

[1 2 5 8]

The original array has been modified.

Important Difference

MethodOriginal modified?Returns sorted array?
np.sort(arr)NoYes
arr.sort()YesNo useful sorted copy

This distinction is important when writing larger programs.


15. The kind Parameter

The kind parameter specifies the sorting algorithm.

Syntax:

np.sort(arr, kind="quicksort")

Common sorting kinds include:

quicksort
heapsort
mergesort
stable

Example:

arr = np.array([8, 3, 7, 1, 9, 2])

result = np.sort(arr, kind="quicksort")

print(result)

Output:

[1 2 3 7 8 9]

The result is sorted, while the algorithm used internally depends on the selected kind.


16. Stable Sorting

A stable sorting algorithm preserves the relative ordering of elements that compare equal.

This is particularly important when sorting structured records or data based on multiple attributes.

Example concept:

Name     Marks
Ravi      80
Anita     90
Kiran     80

If sorting by marks, a stable sort can preserve the original relative order of Ravi and Kiran because both have 80.

You can request stable sorting with:

np.sort(arr, kind="stable")

17. Sorting Structured Arrays Using order

NumPy also supports structured arrays.

Consider student data:

students = np.array([
    ("Ravi", 85),
    ("Anita", 92),
    ("Kiran", 78)
], dtype=[("name", "U10"), ("marks", "i4")])

The fields are:

name
marks

Sort by marks:

result = np.sort(students, order="marks")

print(result)

Output will contain the students ordered by their marks.

The important point is:

order="marks"

specifies the field used for sorting.


18. What Is np.concatenate()?

Sorting is only one part of array manipulation.

Sometimes we need to combine multiple arrays.

NumPy provides:

np.concatenate()

for joining arrays along an existing axis.

Basic example:

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

result = np.concatenate((a, b))

print(result)

Output:

[1 2 3 4 5 6]

19. Syntax of np.concatenate()

General syntax:

np.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")

The most commonly used form is:

np.concatenate((a1, a2), axis=0)

Let's understand the important parameters.


20. First Argument: Sequence of Arrays

The arrays are normally provided inside a tuple:

np.concatenate((a, b))

For example:

a = np.array([10, 20, 30])
b = np.array([40, 50, 60])

result = np.concatenate((a, b))

print(result)

Output:

[10 20 30 40 50 60]

You can concatenate more than two arrays:

a = np.array([1, 2])
b = np.array([3, 4])
c = np.array([5, 6])

result = np.concatenate((a, b, c))

print(result)

Output:

[1 2 3 4 5 6]

21. Concatenating 2-D Arrays

Consider:

a = np.array([
    [1, 2],
    [3, 4]
])

b = np.array([
    [5, 6],
    [7, 8]
])

The arrays are:

A          B

1 2        5 6
3 4        7 8

Concatenate using:

result = np.concatenate((a, b), axis=0)

print(result)

Output:

[[1 2]
 [3 4]
 [5 6]
 [7 8]]

Here, the arrays are joined vertically.


22. Concatenating Along axis=1

Now:

result = np.concatenate((a, b), axis=1)

print(result)

Output:

[[1 2 5 6]
 [3 4 7 8]]

The arrays are joined horizontally.

Visual representation:

A              B

1 2   +        5 6
3 4            7 8

Result:

1 2 5 6
3 4 7 8

23. Understanding Axis Rules for Concatenation

For 2-D arrays:

axis=0 → concatenate rows
axis=1 → concatenate columns

Example:

a.shape

is:

(2, 2)

and:

b.shape

is:

(2, 2)

With:

axis=0

the number of rows increases:

(2, 2) + (2, 2) → (4, 2)

With:

axis=1

the number of columns increases:

(2, 2) + (2, 2) → (2, 4)

24. Concatenating 1-D Arrays

Example:

a = np.array([10, 20, 30])
b = np.array([40, 50])

result = np.concatenate((a, b))

print(result)

Output:

[10 20 30 40 50]

For one-dimensional arrays, concatenation simply joins the elements.


25. Adding Elements Using np.concatenate()

NumPy arrays have a fixed-size structure, so adding an element does not work exactly like Python's list append().

Instead, you can create a new array using concatenation.

Example:

arr = np.array([10, 20, 30])

new_element = np.array([40])

result = np.concatenate((arr, new_element))

print(result)

Output:

[10 20 30 40]

Another convenient function is:

np.append()

Example:

arr = np.array([10, 20, 30])

result = np.append(arr, 40)

print(result)

Output:

[10 20 30 40]

However, np.append() also creates a new array rather than dynamically expanding the existing array.


26. Removing Elements from an Array

NumPy provides:

np.delete()

Example:

arr = np.array([10, 20, 30, 40, 50])

result = np.delete(arr, 2)

print(result)

Output:

[10 20 40 50]

Index 2 corresponds to:

10 → index 0
20 → index 1
30 → index 2
40 → index 3
50 → index 4

Therefore, 30 is removed.

The original array remains unchanged:

print(arr)

Output:

[10 20 30 40 50]

27. Adding, Removing, and Sorting Together

These operations can be combined.

Example:

import numpy as np

arr = np.array([40, 10, 30, 20])

# Add an element
arr = np.append(arr, 50)

# Remove an element
arr = np.delete(arr, 1)

# Sort the array
arr = np.sort(arr)

print(arr)

Let's follow the process.

Initial:

[40 10 30 20]

After adding 50:

[40 10 30 20 50]

Remove index 1:

[40 30 20 50]

Sort:

[20 30 40 50]

Final output:

[20 30 40 50]

28. np.argsort()

np.sort() returns sorted values.

But sometimes we need to know:

At which indexes would the elements appear after sorting?

This is where:

np.argsort()

is useful.

Example:

arr = np.array([30, 10, 20])

indices = np.argsort(arr)

print(indices)

Output:

[1 2 0]

Why?

Original:

Index:  0   1   2
Value: 30  10  20

Sorted values:

10 20 30

Their original indexes are:

1  2  0

Therefore:

np.argsort(arr)

returns:

[1 2 0]

29. Using argsort() to Sort Another Array

This becomes very useful with related data.

Consider:

names = np.array(["Ravi", "Anita", "Kiran"])
marks = np.array([75, 95, 85])

We want to sort students according to marks.

First:

indices = np.argsort(marks)

Then:

print(names[indices])
print(marks[indices])

Output:

['Ravi' 'Kiran' 'Anita']
[75 85 95]

This technique is extremely useful in data analysis.


30. np.lexsort()

Sometimes data needs to be sorted using multiple keys.

For example, suppose we have:

Department
Marks

We may want to sort:

  1. By department

  2. Then by marks

np.lexsort() performs an indirect stable sort using multiple keys.

Conceptually:

np.lexsort((marks, departments))

The last key supplied is the primary sorting key.

Example:

names = np.array(["Ravi", "Anita", "Kiran", "Meena"])
marks = np.array([80, 90, 80, 70])

You can use multiple keys when the problem requires secondary sorting.

This is especially useful for:

  • Student records

  • Employee records

  • Sales data

  • Database-like datasets

  • Multi-column data analysis


31. np.searchsorted()

Suppose an array is already sorted:

arr = np.array([10, 20, 30, 40, 50])

We want to determine where 35 should be inserted while keeping the array sorted.

Use:

position = np.searchsorted(arr, 35)

print(position)

Output:

3

Why?

10 20 30 35 40 50
         ↑
       index 3

Therefore, 35 should be inserted at index 3.


32. Using searchsorted() with Multiple Values

You can search for multiple values:

arr = np.array([10, 20, 30, 40, 50])

result = np.searchsorted(arr, [15, 35, 45])

print(result)

Output:

[1 3 4]

Meaning:

15 → index 1
35 → index 3
45 → index 4

33. np.partition()

Sometimes we don't need a completely sorted array.

Suppose we only want the smallest few elements.

np.partition() performs a partial sorting operation.

Example:

arr = np.array([9, 4, 7, 1, 5, 3])

result = np.partition(arr, 2)

print(result)

The element at index 2 is positioned as it would be in the sorted ordering, while the array as a whole is not necessarily fully sorted.

This can be useful when working with:

  • Top-k problems

  • Smallest-k values

  • Largest-k values

  • Selection algorithms

  • Large datasets


34. sort() vs argsort() vs lexsort() vs searchsorted() vs partition()

These functions have different purposes.

FunctionPurpose
np.sort()Returns sorted values
np.argsort()Returns indexes that produce sorted order
np.lexsort()Sorts using multiple keys
np.searchsorted()Finds insertion position in a sorted array
np.partition()Performs partial sorting

A simple way to remember them:

sort       → Give me sorted values
argsort    → Give me sorting indexes
lexsort    → Sort using multiple keys
searchsorted → Where should this value go?
partition  → Give me partial ordering

35. Practical Example: Student Marks

Let's combine several concepts.

import numpy as np

marks = np.array([78, 92, 65, 88, 71])

print("Original:", marks)

sorted_marks = np.sort(marks)

print("Sorted:", sorted_marks)

indices = np.argsort(marks)

print("Sorting indexes:", indices)

Output:

Original: [78 92 65 88 71]
Sorted: [65 71 78 88 92]
Sorting indexes: [2 4 0 3 1]

36. Practical Example: Combining Student Marks

Suppose one class has:

class_a = np.array([75, 82, 91])

and another class has:

class_b = np.array([68, 88, 79])

Combine them:

all_marks = np.concatenate((class_a, class_b))

print(all_marks)

Output:

[75 82 91 68 88 79]

Now sort:

sorted_marks = np.sort(all_marks)

print(sorted_marks)

Output:

[68 75 79 82 88 91]

37. Practical Example: Combining and Sorting Arrays

import numpy as np

first = np.array([50, 20, 80])
second = np.array([10, 70, 30])

combined = np.concatenate((first, second))

print("Combined:", combined)

sorted_array = np.sort(combined)

print("Sorted:", sorted_array)

Output:

Combined: [50 20 80 10 70 30]
Sorted: [10 20 30 50 70 80]

38. Common Mistake: Forgetting That np.sort() Returns a Copy

Incorrect assumption:

arr = np.array([3, 1, 2])

np.sort(arr)

print(arr)

Output:

[3 1 2]

Why?

Because np.sort() returned a new sorted array, but we did not store it.

Correct:

arr = np.array([3, 1, 2])

arr = np.sort(arr)

print(arr)

Output:

[1 2 3]

Or:

sorted_arr = np.sort(arr)

39. Common Mistake: Incorrect Dimensions in concatenate()

Consider:

a = np.array([
    [1, 2],
    [3, 4]
])

b = np.array([
    [5, 6, 7]
])

Trying:

np.concatenate((a, b), axis=1)

will fail because the dimensions along the other axis do not match.

For concatenation along axis=1, the number of rows must match.

a has:

2 rows

while b has:

1 row

Therefore they cannot be concatenated along axis=1.


40. Concatenation Rule to Remember

When concatenating arrays:

Dimensions must match in every axis except the axis along which concatenation occurs.

For example:

A = (2, 3)
B = (4, 3)

These can be concatenated along:

axis=0

because:

columns = 3
columns = 3

Result:

(6, 3)

But they cannot be concatenated along:

axis=1

because the number of rows differs:

2 != 4

41. NumPy Array Manipulation Summary

The most commonly used functions are:

np.concatenate()
np.append()
np.delete()
np.sort()
np.argsort()
np.lexsort()
np.searchsorted()
np.partition()

Their purposes can be summarized as:

Add        → np.append()
Combine    → np.concatenate()
Remove     → np.delete()
Sort       → np.sort()
Sort index → np.argsort()
Multi-key  → np.lexsort()
Find place → np.searchsorted()
Partial sort → np.partition()

42. Complete Example

The following program demonstrates adding, removing, combining, and sorting.

import numpy as np

# Original arrays
a = np.array([40, 10, 30])
b = np.array([20, 50, 60])

print("Array A:", a)
print("Array B:", b)

# Combine arrays
combined = np.concatenate((a, b))

print("Combined:", combined)

# Add an element
combined = np.append(combined, 70)

print("After adding 70:", combined)

# Remove element at index 1
combined = np.delete(combined, 1)

print("After deleting index 1:", combined)

# Sort
sorted_array = np.sort(combined)

print("Sorted:", sorted_array)

# Get sorting indexes
indices = np.argsort(combined)

print("Sorting indexes:", indices)

This example demonstrates the complete workflow:

Create
   ↓
Combine
   ↓
Add
   ↓
Remove
   ↓
Sort
   ↓
Find sorting indexes

43. Important Interview Questions

Question 1

What does np.sort() return?

Answer: A sorted copy of the input array.

Question 2

Does np.sort() modify the original array?

Answer: No, normally it returns a new sorted array.

Question 3

What does axis=0 mean for a 2-D array?

Answer: Operations proceed along the first axis, so sorting occurs independently within columns.

Question 4

What does axis=1 mean?

Answer: Operations proceed along the second axis, so sorting occurs independently within rows.

Question 5

What is the difference between np.sort() and np.argsort()?

Answer:

np.sort()    → sorted values
np.argsort() → indexes that produce sorted values

Question 6

What does np.concatenate() do?

Answer: It joins a sequence of arrays along an existing axis.

Question 7

Can arrays with different shapes always be concatenated?

Answer: No. Their dimensions must be compatible, with matching dimensions on axes other than the concatenation axis.

Question 8

What does np.searchsorted() do?

Answer: It finds the index at which values should be inserted into a sorted array while maintaining sorted order.


44. Practice Exercises

Try solving these without looking at the solutions first.

Exercise 1 — Basic Sorting

Create:

arr = np.array([45, 12, 78, 23, 9, 56])

Sort the array using np.sort().

Expected output:

[9 12 23 45 56 78]

Exercise 2 — Descending Order

Create:

arr = np.array([10, 50, 20, 40, 30])

Sort it in descending order.

Expected output:

[50 40 30 20 10]

Exercise 3 — Row-wise Sorting

Given:

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

Sort every row independently.

Expected output:

[[2 7 9]
 [1 4 8]
 [3 5 6]]

Exercise 4 — Concatenate Arrays

Given:

a = np.array([10, 20, 30])
b = np.array([40, 50, 60])

Use np.concatenate() to produce:

[10 20 30 40 50 60]

Exercise 5 — Combined Problem

Given:

a = np.array([40, 10, 70])
b = np.array([20, 90, 30])

Perform the following operations:

  1. Concatenate both arrays.

  2. Add 50.

  3. Remove the value 10.

  4. Sort the resulting array.

  5. Find the indexes that produce the sorted order.

Try to solve it using:

np.concatenate()
np.append()
np.delete()
np.sort()
np.argsort()

45. Quick Revision

Remember these core NumPy operations:

# Sort
np.sort(arr)

# Sort in descending order
np.sort(arr)[::-1]

# Concatenate
np.concatenate((a, b))

# Add
np.append(arr, value)

# Remove
np.delete(arr, index)

# Sorting indexes
np.argsort(arr)

# Multi-key sorting
np.lexsort(keys)

# Find insertion position
np.searchsorted(arr, value)

# Partial sorting
np.partition(arr, kth)

46. Final Takeaway

Array manipulation is one of the fundamental skills required for effective NumPy programming.

The most important functions covered in this article are:

np.sort()

Used when you need the sorted values of an array.

np.sort(arr)

np.concatenate()

Used when you need to join arrays along an existing axis.

np.concatenate((a, b))

np.argsort()

Used when you need the indexes that produce sorted order.

np.argsort(arr)

np.lexsort()

Useful when sorting according to multiple keys.

np.searchsorted()

Useful for finding the correct insertion position in a sorted array.

np.partition()

Useful when you need partial ordering rather than complete sorting.

Understanding these operations gives you a strong foundation for more advanced NumPy topics such as:

  • Boolean indexing

  • Fancy indexing

  • Broadcasting

  • Aggregation functions

  • Statistical operations

  • Matrix operations

  • Data cleaning

  • Pandas integration

  • Machine learning preprocessing



Comments