NumPy arrays

Part of the free LogicWiz Python course, Module 10: NumPy and pandas. The examples and practice run in the app.

Shankar bhaiya wants every price up by 10%. Meher typed prices * 1.1 on her list and got a TypeError. Then she tried prices * 2 and got a list twice as long. A list is not a column of numbers, but a NumPy array is.

You'll learn to

  • Make arrays with `np.array`, `arange`, `zeros`, `ones` and `linspace`
  • Read an array's `shape`, `ndim`, `size` and `dtype`
  • Do maths on a whole array at once (vectorised maths)

Learn

Why arrays?

A Python list can hold anything: numbers, strings, other lists. That freedom makes it slow for maths, and + and * mean join and repeat.

A NumPy array holds values of one type, packed tightly in memory, and its operators do maths on every element. arr * 2 doubles each number, with the loop running in fast C code instead of Python. This is called vectorised maths.

Everyone imports it the same way: import numpy as np.

List maths vs array maths

import numpy as np

prices = [15, 10, 60]
print(prices * 2)                 # a list repeats itself
arr = np.array(prices)
print(arr * 2)                    # an array doubles every value
print(arr * 1.1)
print(arr + np.array([1, 2, 3]))  # element by element
print(arr > 12)                   # comparisons work too

Arrays print without commas: [30 20 120]. That is how you tell an array from a list in output.

Shape, size and dtype

import numpy as np

marks = np.array([[78, 85, 90],
                  [66, 72, 80]])
print(marks.shape, marks.ndim, marks.size)
print(marks.dtype)                 # an integer type, e.g. int64
print(np.array([1, 2.5]).dtype)    # one float makes them all floats
print(np.array([1, "2"]))          # one string makes them all strings

shape is (rows, columns); ndim is the number of dimensions; size is the count of all values. The exact integer dtype can be int64 or int32 depending on the machine.

Ready-made arrays

import numpy as np

print(np.arange(5))              # like range(5)
print(np.arange(10, 50, 10))     # start, stop (excluded), step
print(np.zeros(4))
print(np.ones((2, 3)))
print(np.full(3, 7))
print(np.linspace(0, 1, 5))      # 5 evenly spaced values, end included

A canteen bill without a single loop

import numpy as np

price = np.array([15, 10, 60, 25])
qty = np.array([4, 10, 2, 3])
amount = price * qty
print(amount)
print(amount.sum(), amount.max(), amount.argmax())
print(np.round(amount * 1.05, 2))
print(amount.mean())

argmax() gives the position of the largest value (the dosas, at position 2). np.round(x, 2) rounds every element.

An array keeps its type. Put 2.7 into an integer array and NumPy silently cuts it to 2. And np.array(1, 2, 3) is an error: pass one list, np.array([1, 2, 3]).

CBSE IP practicals start with "Create a pandas Series from a dictionary of values and from an ndarray". That ndarray is a NumPy array: np.array([...]). Interviews for data roles ask "Why is NumPy faster than a list?": one data type, contiguous memory, and loops in C (vectorisation).

In one line

A NumPy array holds one type; arr * 2, arr + arr and np.sqrt(arr) work on every element at once (vectorised); read shape, ndim, size, dtype.

Interview corner

Why is a NumPy array faster than a Python list?

An array stores values of one fixed type in one contiguous block of memory, while a list stores pointers to separate Python objects. Operations on arrays run as compiled C loops (vectorisation) with no per-element Python overhead. It also uses much less memory.

What is vectorisation?

Writing an operation on a whole array instead of looping over its elements in Python: amount = price * qty instead of a for loop. NumPy runs the loop internally in C, which is often 10-100× faster and shorter to read.

What is the difference between `shape`, `size` and `ndim`?

shape is a tuple of the length of each dimension, e.g. (3, 4); ndim is the number of dimensions (2); size is the total number of elements (12). All three are attributes, not methods.