Creating Arrays and dtypes
Overview
Where an array comes from, and the type it settles on.
What You Will Learn in This Lesson
By the end of this lesson, you will be able to:
- Build an array from a list, from a range, and from a fill value.
- Choose between
arangeandlinspacefor the job in front of you. - Explain why one float in a list of ints changes the whole array.
- Set a dtype deliberately instead of accepting the one you were given.
Why This Matters
The dtype is decided at the moment the array is made, and it is decided silently. A column that should be whole numbers arriving as floats, or an integer array quietly truncating the decimals you assign into it, both start here. Two minutes on where arrays come from saves a long afternoon later.
Step 1: Several ways in
Most arrays come from one of four places: an existing list, a range of numbers, a fill value, or a file. The first three are here; files arrive in unit 5.
From a list, and from a count
np.array converts what you already have. np.zeros and np.ones make an array of a given size to fill in later, which is useful when you know the shape before you know the values.
import numpy as np
print(np.array([1, 2, 3]))
print(np.zeros(3))
print(np.ones(3))
print(np.full(3, 7))
arange steps, linspace divides
arange takes a start, a stop and a step, and the stop is exclusive — exactly like range. linspace takes a start, a stop and a count, and the stop is included. Use arange when you know the step, linspace when you know how many points you want.
import numpy as np
# step of 2, stopping below 10
print(np.arange(0, 10, 2))
# five points from 0 to 1, both ends included
print(np.linspace(0, 1, 5))
The exclusive stop on arange is the single most common off-by-one in numpy. np.arange(0, 10, 2) has five elements, not six.
Mini Practice #1: arange or linspace
Try It YourselfProduce the numbers 0, 0.25, 0.5, 0.75, 1 twice — once with arange and once with linspace. Notice which one needed you to think about the exclusive stop.
Step 2: The dtype is chosen for you, until it is not
Everything in an array shares one type. When you build from a list, numpy picks the narrowest type that can hold all of it.
One float widens everything
A single decimal in a list of whole numbers makes the entire array float, because there is no way to keep one element different from the rest. This is why an id column read from a messy file sometimes prints as 3.0.
import numpy as np
print(np.array([1, 2, 3]).dtype)
print(np.array([1, 2, 3.0]).dtype)
print(np.array([1, 2, 3.0]))
Saying what you want
Pass dtype to decide rather than discover. It converts, so asking for float gives you floats even from whole numbers.
import numpy as np
print(np.array([1, 2, 3], dtype=float))
print(np.array([1.9, 2.9], dtype=int))
Converting to int truncates towards zero — it does not round. 1.9 becomes 1.
The trap on the way back in
The dtype belongs to the array, not to the value you assign. Writing a float into an int array truncates it, silently, with nothing raised.
import numpy as np
a = np.array([1, 2, 3])
a[0] = 3.7
print(a) # the 3.7 became 3
print(a.dtype)
Mini Practice #2: Predict the dtype
Try It YourselfBefore running, write down what each line will print. The last two are the ones worth getting wrong once.
Step 3: When to Use It
Converting data you already have
np.array on a list of numbers, then check dtype so you know what arithmetic will do.
arr = np.array(values, dtype=float)
Generating ranges and placeholders
arange, linspace, zeros and ones for sequences and blank arrays of a known size.
When Not to Use It
Do not ignore the dtype. A column that settled on an integer type truncates when you store a fraction into it, and one that settled on object has lost the speed entirely.
End-of-Lesson Exercises
Exercise 1: Even numbers below a stop
Write even_numbers(stop) that returns a numpy array of the even numbers from 0 up to but not including stop.
np.arange takes a start, a stop and a step. The stop is exclusive, the same way range works.
Exercise 2: Evenly spaced readings
Write readings(start, end, count) that returns a numpy array of count evenly spaced values from start to end, with both ends included, as a float array.
This is exactly what np.linspace is for: it takes the count, not the step, and includes the end.