Free Study Material
Lists can hold numbers, but they weren't built specifically for fast, large-scale numeric work. This chapter introduces the library CBSE IP uses for exactly that: NumPy.
NumPy (Numerical Python) is a Python library built for fast, efficient work with numeric data, especially large collections of numbers. Its core data structure is the ndarray (N-dimensional array) — a grid of values, all of the same data type, that NumPy can operate on as a whole, far faster than looping over an ordinary Python list by hand.
A regular Python list can hold mixed types and grows one flexible element at a time — general-purpose, but not optimised for numeric-heavy work. An ndarray trades that flexibility (every element must share one type) for real speed: NumPy performs operations across an entire array at once, internally, instead of Python looping over each element individually — which is exactly why NumPy is the standard tool once a program moves from a handful of numbers to genuinely large numeric datasets.
Note: "ndarray" and "NumPy array" mean the same thing in this chapter — ndarray is the formal name of the object; "NumPy array" is the everyday name for it.
NumPy is a library for fast, efficient numeric computing, built around the ndarray — a grid of same-typed values NumPy can operate on as a whole, far faster than looping over a Python list by hand.
NumPy stands for Numerical Python. It is an open-source library that acts as the backbone for almost all data science and machine learning tasks in Python. While standard Python is great for general logic, it lacks the raw speed required for heavy mathematical computations on large data sets.
To understand why we use NumPy in Informatics Practices, we must look at how data is stored in your computer's RAM.
import numpy as np
# Rule 1: Standard Lists are flexible but slow
list_data = [1, "Apple", 3.14]
print("List allows everything:", list_data)
# Output: [1, 'Apple', 3.14]
# Rule 2: NumPy Arrays force data into a single type (Homogeneous)
# If you mix types, NumPy converts them to a common type (usually String)
arr_data = np.array([1, "Apple", 3.14])
print("Array forces strings:", arr_data)
# Output: ['1' 'Apple' '3.14']
import numpy as np
# Rule 3: Math on Lists repeats the data
L = [1, 2, 3]
print("List Multiplication:", L * 2)
# Output: [1, 2, 3, 1, 2, 3]
# Rule 4: Math on Arrays is 'Element-wise' (Vectorized)
A = np.array([1, 2, 3])
print("Array Multiplication:", A * 2)
# Output: [2, 4, 6]
Before creating your first array in the next topic, this covers how NumPy is brought into a program, and the properties every array carries with it.
NumPy is brought in with:
import numpy as np
np is the standard, universally-used alias for NumPy — every NumPy function is then called as np.function_name(...).
Every ndarray carries these properties:
import numpy as np
marks = np.array([78, 85, 92, 67])
print(marks.ndim)
print(marks.shape)
print(marks.size)
print(marks.dtype)
marks.ndim is 1 (a single row of values). marks.shape is (4,) — one dimension, with 4 elements along it. marks.size is 4. marks.dtype reports the shared element type NumPy chose automatically — int64 (or a similarly-named integer type), since every value here is a whole number.
Note:shapeis always a tuple, even for a 1-dimensional array —(4,), not just4. The trailing comma is what makes it a one-element tuple rather than a plain number in parentheses.
dtype is the property with no real list equivalent — a Python list can freely mix an int and a str in the same list, but every element of an ndarray shares exactly one dtype, which is precisely the constraint that lets NumPy operate on the whole array so efficiently.
import numpy as np is the standard way to bring in NumPy. Every ndarray carries ndim (number of dimensions), shape (size along each dimension, as a tuple), size (total element count), and dtype (the one shared element type).
NumPy is a third-party library, meaning it is not part of the standard Python core. To use its features, you must bring it into your script using the import keyword. In data science, there is a global convention to use an Alias (a shorter name) to make the code cleaner.
While you can name it anything, almost every programmer in the world uses np. This is helpful when you are reading code from other developers or documentation.
import numpy as np
Once an array is created, it has built-in properties (attributes) that tell us about its structure and the data it contains. These are essential for debugging and data validation.
# Rule: Use 'import numpy as np' for standard practice
import numpy as np
# Creating a basic array to check its type
my_arr = np.array([1, 2, 3])
print("Object Category:", type(my_arr))
# Output: Object Category: <class 'numpy.ndarray'>
print("NumPy Version:", np.__version__)
# Output: NumPy Version: 1.26.x
import numpy as np
# Creating an array with different properties
data = np.array([1.5, 2.5, 3.5, 4.5])
# Rule: .dtype reveals how NumPy is storing the numbers
print("Internal Data Type:", data.dtype)
# Output: Internal Data Type: float64
# Rule: .size gives the total count of items
print("Total Elements:", data.size)
# Output: Total Elements: 4
# Rule: .shape for a 1D array returns (n,)
print("Array Shape:", data.shape)
# Output: Array Shape: (4,)
Now that you know an array's basic properties, this topic covers actually creating one — starting from a plain Python list, the most common starting point.
np.array(list) converts a Python list into an ndarray. Passing a list of lists creates a 2-dimensional array — a grid of rows and columns, indexed with array[row][col] or the NumPy-specific array[row, col].
import numpy as np
marks_1d = np.array([78, 85, 92])
print(marks_1d)
print(marks_1d[0])
grid_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(grid_2d)
print(grid_2d.ndim)
print(grid_2d[1, 2])
np.array([78, 85, 92]) creates a 1-dimensional array; marks_1d[0] gives 78, using the same indexing you already know from lists. np.array([[1, 2, 3], [4, 5, 6]]) creates a 2-dimensional array — two rows of three columns each — so grid_2d.ndim is 2. grid_2d[1, 2] reaches row index 1, column index 2: the value 6.
Note:array[1, 2](comma inside one set of brackets) is NumPy's own indexing style for a 2D array — a plain Python list of lists would instead needarray[1][2], two separate sets of brackets. Both styles work on an ndarray; only the comma style works purely because it's a NumPy array.
Converting an existing list with np.array() is the most common way an ndarray gets created in practice — it's how ordinary data (marks already collected in a list, for instance) becomes something NumPy can operate on efficiently as a whole.
np.array(list) converts a Python list into an ndarray — a list of lists becomes a 2-dimensional array, indexable either the list-of-lists way (array[row][col]) or NumPy's own comma style (array[row, col]).
The primary way to create a NumPy array is by passing a sequence (like a Python List) as an argument to the np.array() function. This converts the flexible, slow Python list into a high-performance, contiguous ndarray.
A 1-Dimensional array is created by passing a single list of elements. This is often used to represent a single feature in a dataset, such as "Age" or "Price".
array_name = np.array([element1, element2, ...])
Because NumPy arrays must be Homogeneous (all elements of the same type), NumPy has to decide what to do when you provide a list with mixed data types. It follows a rule called Upcasting—it converts all elements to the most "complex" type present in the list to avoid losing information.
import numpy as np
# Rule 1: Passing a list to np.array() creates a 1D array
marks_list = [78, 92, 85, 90]
marks_arr = np.array(marks_list)
print("Standard List:", marks_list)
# Output: [78, 92, 85, 90]
print("NumPy Array:", marks_arr)
# Output: [78 92 85 90] (Notice: No commas in the output display)
import numpy as np
# Rule 2: Mixing Ints and Floats converts all to Floats
mixed_data = [10, 20.5, 30]
arr1 = np.array(mixed_data)
print("Result of Int + Float:", arr1)
# Output: [10. 20.5 30. ]
# Rule 3: Adding even one String converts everything to String
mixed_data_2 = [10, "IP", 20.5]
arr2 = np.array(mixed_data_2)
print("Result of mixed with String:", arr2)
# Output: ['10' 'IP' '20.5']