PYTHON FOR AI • LESSON 2

Indexing

Indexing means accessing a specific element inside a NumPy array. Once you understand indexes, you can select individual values, rows, columns, and specific elements from your data.

CORE IDEA

Indexing tells NumPy which element you want.

Python and NumPy use zero-based indexing. That means the first element is at index 0, the second is at index 1, and so on.

01

What Is Indexing?

Suppose we have this NumPy array:

import numpy as np

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

The array looks like this:

Value:    10   20   30   40   50
Index:     0    1    2    3    4

If we want the value 30, we use index 2.

print(numbers[2])
30
02

Zero-Based Indexing

The most important rule is: count from 0, not 1.

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

print(numbers[0])
print(numbers[1])
print(numbers[2])
print(numbers[3])
print(numbers[4])
10
20
30
40
50

The mapping is:

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

If you try to use index 5, there is no sixth element, so NumPy will raise an IndexError.

03

Negative Indexing

NumPy also supports negative indexes. Negative indexing starts from the end of the array.

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

print(numbers[-1])
print(numbers[-2])
print(numbers[-3])
50
40
30

Think of it like this:

Value:     10   20   30   40   50
Positive:   0    1    2    3    4
Negative:  -5   -4   -3   -2   -1

So numbers[-1] always gives the last element.

04

Indexing a 2D Array

Things become slightly different when the array has rows and columns.

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

Think about the indexes:

          Column
          0    1    2

Row 0     10   20   30
Row 1     40   50   60

To access an element in a 2D array, use:

array[row, column]

For example, to get 50:

print(data[1, 1])
50

Why?

data[1, 1]
     ↑  ↑
     │  └── column 1
     └───── row 1
05

More 2D Indexing Examples

Using the same array:

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

Get 10:

print(data[0, 0])
10

Get 30:

print(data[0, 2])
30

Get 60:

print(data[1, 2])
60
06

Accessing a Complete Row

You can also select an entire row.

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

print(data[0])
[10 20 30]

Here data[0] means:

Give me row 0.

To get the second row:

print(data[1])
[40 50 60]
07

Accessing a Complete Column

To get a complete column, use a colon : for the row and specify the column.

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

print(data[:, 1])
[20 50]

Read this as:

data[:, 1]
     ↑  ↑
     │  └── column 1
     └───── all rows

Therefore it returns:

20
50

The same idea can be used for the first column:

print(data[:, 0])
[10 40]
08

Negative Indexing in 2D Arrays

Negative indexing also works with rows and columns.

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

print(data[-1, -1])
60

This means:

-1 row    → last row
-1 column → last column

Therefore:

data[-1, -1]
→ 60
09

Indexing a 3D Array

A 3D array needs three indexes.

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

Its shape is:

data.shape

(2, 2, 2)

To access the value 7:

print(data[1, 1, 0])
7

The three indexes represent the three dimensions:

data[1, 1, 0]
     ↑  ↑  ↑
     │  │  └── position inside the row
     │  └───── row
     └──────── block

You don't need to memorize complicated 3D indexing yet. The important rule is simple: one index for each dimension.

10

Changing an Element Using Indexing

Indexing is not only for reading values. You can also use an index to change a value.

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

numbers[2] = 100

print(numbers)
[10 20 100 40 50]

The value at index 2 was changed:

Before:
[10 20 30 40 50]

After:
[10 20 100 40 50]
11

Indexing AI Dataset Data

Imagine a dataset containing information about students.

students = np.array([
    [20, 170, 65],
    [22, 175, 70],
    [25, 180, 80],
    [21, 168, 60]
])

We can think of the columns as:

Column 0 → Age
Column 1 → Height
Column 2 → Weight

To get the age of the third student:

print(students[2, 0])
25

To get the weight of the second student:

print(students[1, 2])
70

This is exactly the type of indexing you will use when working with real datasets in Data Science and AI.

12

Common Indexing Mistake

A common beginner mistake is forgetting that indexing starts at zero.

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

print(numbers[1])

Some beginners expect 30 because they think "1" means the first position.

But Python uses zero-based indexing:

numbers[0] → 10
numbers[1] → 20
numbers[2] → 30

So numbers[1] returns 20.

13

Complete Example

Let's combine the most important indexing concepts.

import numpy as np

students = np.array([
    [20, 170, 65],
    [22, 175, 70],
    [25, 180, 80]
])

print("First student:")
print(students[0])

print("Second student's height:")
print(students[1, 1])

print("Third student's weight:")
print(students[2, 2])

print("All heights:")
print(students[:, 1])

print("Last student:")
print(students[-1])
First student:
[ 20 170  65]

Second student's height:
175

Third student's weight:
80

All heights:
[170 175 180]

Last student:
[ 25 180  80]
14

Simple Indexing Rules

Code Meaning
array[0] First element
array[-1] Last element
array[1, 2] Row 1, Column 2
array[0] First row of a 2D array
array[:, 0] All rows from Column 0
array[-1, -1] Last row, Last column
KEY TAKEAWAY

Indexing lets you access exactly the data you need.

NumPy uses zero-based indexing. For a 1D array, array[0] accesses the first element. For a 2D array, array[row, column] accesses a specific value. You can also use negative indexes to access values from the end and : to select complete rows or columns. These skills are essential when working with datasets in AI and Machine Learning.