NumPy Arrays & dtypes

Data Science · Lesson 3 of 32 7 min read Updated

Every number-crunching library in Python, including pandas, matplotlib and scikit-learn, is built on NumPy (Numerical Python). Its core object is the array: a grid of values that all have the same type, stored side by side in memory.

In this lesson you will create arrays in several ways, read their shape and type, and learn about dtypes, the data types that decide how much memory each value takes and what maths you can do with it.

Why not just use lists?

A Python list can hold anything, and that flexibility makes it slow for maths. Look at what happens when you try to double some prices.

PythonRun it yourself
import numpy as np

prices_list = [120, 80, 45, 300]
print(prices_list * 2)

prices = np.array([120, 80, 45, 300])
print(prices * 2)
print(prices + 18)
Output
[120, 80, 45, 300, 120, 80, 45, 300]
[240 160  90 600]
[138  98  63 318]

Multiplying a list by 2 repeats the list. Multiplying an array by 2 doubles every value. Adding 18 adds it to every element too. This style, where one operation works on the whole array without a loop, is called vectorised code. It is shorter to write and much faster to run, because NumPy does the loop in compiled C code instead of Python.

Arrays are fast for two more reasons: every element has the same type, so NumPy knows exactly how many bytes each one uses, and the values sit in one continuous block of memory.

Creating arrays

You will create arrays from lists most often, but NumPy has helpers for common patterns.

PythonRun it yourself
import numpy as np

marks = np.array([[78, 65, 90], [88, 72, 81]])   # 2 students x 3 subjects
print(marks)

print(np.arange(0, 20, 5))         # start, stop (excluded), step
print(np.linspace(0, 1, 5))        # 5 evenly spaced values from 0 to 1
print(np.zeros(3))
print(np.ones((2, 3), dtype=int))
print(np.full(4, 7.5))
Output
[[78 65 90]
 [88 72 81]]
[ 0  5 10 15]
[0.   0.25 0.5  0.75 1.  ]
[0. 0. 0.]
[[1 1 1]
 [1 1 1]]
[7.5 7.5 7.5 7.5]
  • np.array() turns a list, or a list of lists, into an array. A list of lists becomes a 2-D array, like a table with rows and columns.
  • np.arange() works like Python's range() but returns an array and also accepts decimal steps.
  • np.linspace() gives a fixed number of evenly spaced points, including both ends. It is handy for drawing smooth curves.
  • np.zeros(), np.ones() and np.full() create arrays of a given shape filled with one value. A shape with more than one dimension is written as a tuple, such as (2, 3).

Shape, ndim, size and dtype

Every array knows its own size and type. These attributes are the first thing to check when code behaves strangely.

PythonRun it yourself
import numpy as np

rainfall = np.array([[12.5, 0.0, 33.1, 4.2],
                     [0.0, 8.4, 51.0, 19.7],
                     [2.2, 0.0, 0.0, 6.5]])

print("shape:", rainfall.shape)    # (rows, columns)
print("ndim: ", rainfall.ndim)     # number of dimensions
print("size: ", rainfall.size)     # total number of values
print("dtype:", rainfall.dtype)
print("bytes:", rainfall.nbytes)

weekly = rainfall.reshape(4, 3)
print(weekly)
print(np.arange(12).reshape(3, -1))
Output
shape: (3, 4)
ndim:  2
size:  12
dtype: float64
bytes: 96
[[12.5  0.  33.1]
 [ 4.2  0.   8.4]
 [51.  19.7  2.2]
 [ 0.   0.   6.5]]
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

shape is a tuple: 3 rows (say, three cities) and 4 columns (four weeks). size is 3 × 4 = 12, and because each float64 value uses 8 bytes, nbytes is 96. reshape() gives the same values a new shape, as long as the total size stays the same. Passing -1 for one dimension tells NumPy to work it out for you.

Understanding dtypes

The dtype (data type) says how each value is stored. These are the ones you will meet most:

dtypeHoldsExample
int64Whole numbers, 8 bytes each (int32 uses 4)quantities, years
float64Decimal numbers, 8 bytes eachprices, temperatures
boolTrue or False"is the order late?"
<U7Fixed-length text (here, up to 7 characters)city names
int8, int32, float32Smaller types that save memorylarge image or sensor data

NumPy picks a dtype from your data, and an array can only have one. If you mix types, NumPy upcasts every value to a type that can hold them all. You can also convert with astype().

PythonRun it yourself
import numpy as np

print(np.array([1, 2, 3]).dtype)
print(np.array([1, 2, 3.5]).dtype)          # one float makes all floats
print(np.array([1, "Pune"]).dtype)          # everything becomes text
print(np.array([10, 0, 7]) > 5)

temps = np.array([31.7, 29.2, 35.9])
print(temps.astype(int))                    # cuts off the decimals
print(np.round(temps).astype(int))          # round first, then convert

small = np.array([120, 125], dtype=np.int8)  # int8 holds -128 to 127
print(small + 10)
Output
int32
float64
<U11
[ True False  True]
[31 29 35]
[32 29 36]
[-126 -121]

The first line printed int32 here. On a normal 64-bit computer it prints int64, which is NumPy's default integer type (since NumPy 2.0 this is true on Windows as well). The browser editor runs on a 32-bit WebAssembly platform, so its default integer is int32; the values behave the same unless they get very large.

Two more results deserve attention. astype(int) does not round: 35.9 becomes 35. Round first if that is what you want. And int8 can only store values from -128 to 127, so 125 + 10 silently overflows and wraps around to a negative number. Use small types only when you know the range of your data.

A slightly bigger example

Arrays shine when you combine these ideas. Here are a week of temperatures in Kochi, converted from Celsius to Fahrenheit and summarised in a few lines.

PythonRun it yourself
import numpy as np

celsius = np.array([29.4, 30.1, 31.0, 30.6, 28.9, 29.8, 30.4])
fahrenheit = celsius * 9 / 5 + 32

print(np.round(fahrenheit, 1))
print("Hottest:", celsius.max(), "°C on day", celsius.argmax() + 1)
print("Average:", round(celsius.mean(), 2), "°C")
print([celsius.max()])
Output
[84.9 86.2 87.8 87.1 84.  85.6 86.7]
Hottest: 31.0 °C on day 3
Average: 30.03 °C
[np.float64(31.0)]

The formula is written once and applied to all seven days. argmax() returns the position of the largest value, counting from 0, which is why we add 1 for a human-friendly day number. The last line shows the NumPy 2 style of displaying a NumPy number inside a list.

Common mistakes

  • Using a list where you meant an array. [1, 2] * 3 repeats the list. Convert with np.array() before doing maths.
  • Mixing text and numbers. One string in the data turns the whole array into text, and maths then fails. Clean the data first.
  • Expecting astype(int) to round. It truncates towards zero. Use np.round() first.
  • Choosing a dtype that is too small. Values outside its range overflow without an error.

Key points

  • A NumPy array holds values of one type in a continuous block of memory, which makes maths fast.
  • Create arrays with np.array(), np.arange(), np.linspace(), np.zeros(), np.ones() and np.full().
  • shape, ndim, size, dtype and nbytes describe an array; reshape() changes its shape.
  • Mixing types upcasts the whole array; astype() converts and truncates decimals.
  • NumPy 2 shows scalars as np.float64(...) and removed old aliases such as np.NaN.

Exercise

A tea stall in Pune records cups sold for 6 days: 140, 152, 138, 175, 210, 198. Create an array, then print its dtype, the total cups, and the average rounded to one decimal place. Finally, reshape it into 2 rows of 3 days and print it.

Show solution
Python
import numpy as np

cups = np.array([140, 152, 138, 175, 210, 198])
print(cups.dtype)
print("Total:", cups.sum())
print("Average:", round(cups.mean(), 1))
print(cups.reshape(2, 3))
Output
int32
Total: 1013
Average: 168.8
[[140 152 138]
 [175 210 198]]

The dtype is int32 in the browser editor and int64 on most computers. The six values fit exactly into a 2 × 3 shape. reshape(4, 2) would fail because 4 × 2 is 8, not 6.

Quick Quiz

1. What does np.array([2, 4]) * 3 produce?

2. What is the dtype of np.array([5, 6, 7.0])?

3. What does np.array([9.8]).astype(int) give?

4. An array has shape (4, 5). What is its size?

Learn Data Science with a mentor

Free lessons get you started. Our Data Science & Machine Learning training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call