Skip to content

Creating NumPy Arrays: array, zeros, ones, full, arange, linspace, eye

In lesson 01 we made arrays from lists. In real programs you often need an array of a certain size filled with a starting value, a range of numbers, or a special matrix. NumPy has a ready-made function for each case, so you almost never build big arrays by hand.

FunctionCreates
np.array(list)an array from existing values
np.zeros(shape) / np.ones(shape)all 0 / all 1
np.full(shape, value)every element the same value
np.arange(start, stop, step)numbers with a fixed step, like range()
np.linspace(start, stop, count)a fixed count of evenly spaced numbers
np.eye(n)an identity matrix (1 on the diagonal, 0 elsewhere)

How to run the examples

Create a new file named array_creation.py in your NumpyTutorials folder (see the setup in lesson 01). Any name works; this one just matches the topic. Start the file with these lines:

import numpy as np

Then copy the examples of this page into the same file, one after another, in the order shown, and run it with python array_creation.py (with your virtual environment active). Some examples use variables created in earlier ones, so keep everything in the one file. Each Output box shows what that example prints.

1. np.array: from lists and tuples

a = np.array([1, 2, 3])                       # from a list
b = np.array((4.5, 5.5, 6.5))                 # from a tuple
c = np.array([[1, 2], [3, 4]])                # from a list of lists -> 2D
d = np.array([1, 2, 3], dtype=float)          # choose the type yourself

print(a, a.dtype)
print(b, b.dtype)
print(c)
print(d, d.dtype)

try:
    np.array([[1, 2], [3]])                   # rows of different length
except ValueError as error:
    print("Error:", error)
Output
[1 2 3] int64
[4.5 5.5 6.5] float64
[[1 2]
 [3 4]]
[1. 2. 3.] float64
Error: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
  • A list or a tuple both work.
  • A list of lists becomes a 2D array.
  • dtype=float chooses the type yourself: [1, 2, 3] becomes [1. 2. 3.]. The dot after a number means it is a float.
  • Every row must have the same length. An array is a rectangle; rows of different lengths give a "inhomogeneous shape" error.

2. np.zeros and np.ones

The most common way to start: an array full of 0 or 1 that you fill in later.

print("zeros(5):\n", np.zeros(5))                     # 1D, float by default
print("zeros((2, 3)):\n", np.zeros((2, 3)))           # shape as a tuple
print("ones((3, 2), dtype=int):\n", np.ones((3, 2), dtype=int))
Output
zeros(5):
 [0. 0. 0. 0. 0.]
zeros((2, 3)):
 [[0. 0. 0.]
 [0. 0. 0.]]
ones((3, 2), dtype=int):
 [[1 1]
 [1 1]
 [1 1]]
  • For more than one dimension, the shape is a tuple: np.zeros((2, 3)) with two pairs of brackets. np.zeros(2, 3) is a common mistake and gives an error.
  • The default type is float64 (0.). Pass dtype=int to get whole numbers.

3. np.full and np.empty

print("full((2, 4), 7):\n", np.full((2, 4), 7))
print("full(3, 'NA'):", np.full(3, "NA"))

# empty() only reserves memory; the values are whatever was there before.
# Use it only when you will fill every element yourself.
scores = np.empty(4)
scores[:] = [10, 20, 30, 40]
print("empty(4) after filling:", scores)
Output
full((2, 4), 7):
 [[7 7 7 7]
 [7 7 7 7]]
full(3, 'NA'): ['NA' 'NA' 'NA']
empty(4) after filling: [10. 20. 30. 40.]
  • np.full(shape, value) fills every element with your value; it even works with text.
  • np.empty() only reserves memory and does not clean it, so it contains random leftover numbers. It is slightly faster than zeros, but use it only when you will overwrite every element straight away, as we do here with scores[:] = [...].

4. zeros_like, ones_like, full_like

Often you need a new array with the same shape and type as one you already have, for example to store results. The _like functions copy the shape and dtype for you:

sales = np.array([[120, 340, 560],
                  [230, 410, 150]])

print("zeros_like:\n", np.zeros_like(sales))
print("ones_like:\n", np.ones_like(sales))
print("full_like(sales, 99):\n", np.full_like(sales, 99))
Output
zeros_like:
 [[0 0 0]
 [0 0 0]]
ones_like:
 [[1 1 1]
 [1 1 1]]
full_like(sales, 99):
 [[99 99 99]
 [99 99 99]]

The values of sales are not copied, only its shape (2, 3) and its type int64.

5. np.arange: like range()

np.arange works like Python's range() but returns an array, and it also accepts decimal steps.

print("arange(5)         :", np.arange(5))              # 0..4
print("arange(1, 11)     :", np.arange(1, 11))          # 1..10 (stop is not included)
print("arange(0, 50, 10) :", np.arange(0, 50, 10))      # step 10
print("arange(10, 0, -2) :", np.arange(10, 0, -2))      # counting down
print("arange(0, 1, 0.25):", np.arange(0, 1, 0.25))     # float step
Output
arange(5)         : [0 1 2 3 4]
arange(1, 11)     : [ 1  2  3  4  5  6  7  8  9 10]
arange(0, 50, 10) : [ 0 10 20 30 40]
arange(10, 0, -2) : [10  8  6  4  2]
arange(0, 1, 0.25): [0.   0.25 0.5  0.75]
  • As with range(), the stop value is not included: arange(1, 11) ends at 10.
  • A negative step counts down.
  • With a decimal step, the number of values can be surprising because of float rounding. For decimals, linspace is usually safer.

6. np.linspace: a fixed number of values

linspace asks a different question: "give me this many evenly spaced values between start and stop".

print("linspace(0, 1, 5)  :", np.linspace(0, 1, 5))             # 5 values, stop included
print("linspace(0, 100, 3):", np.linspace(0, 100, 3))
print("endpoint=False     :", np.linspace(0, 1, 5, endpoint=False))

values, step = np.linspace(0, 10, 6, retstep=True)
print("retstep=True       :", values, "step =", step)

# arange   -> you choose the STEP
# linspace -> you choose the COUNT
Output
linspace(0, 1, 5)  : [0.   0.25 0.5  0.75 1.  ]
linspace(0, 100, 3): [  0.  50. 100.]
endpoint=False     : [0.  0.2 0.4 0.6 0.8]
retstep=True       : [ 0.  2.  4.  6.  8. 10.] step = 2.0
  • Here the stop value is included by default. endpoint=False leaves it out.
  • retstep=True also returns the step NumPy calculated.

arange vs linspace: with arange you choose the step and NumPy works out the count; with linspace you choose the count and NumPy works out the step. Use linspace for things like "100 points on a graph between 0 and 1".

7. np.eye, np.identity and np.diag

An identity matrix has 1 on the main diagonal and 0 everywhere else. It is the "1" of matrix maths: any matrix multiplied by it stays the same (lesson 13).

print("eye(3):\n", np.eye(3))                     # 3x3 identity matrix
print("eye(3, 4, k=1):\n", np.eye(3, 4, k=1))     # 3x4, diagonal moved one place right
print("identity(2, dtype=int):\n", np.identity(2, dtype=int))
print("diag([5, 6, 7]):\n", np.diag([5, 6, 7]))   # given values on the diagonal
print("diag of a matrix:", np.diag(np.array([[1, 2], [3, 4]])))   # read the diagonal
Output
eye(3):
 [[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
eye(3, 4, k=1):
 [[0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
identity(2, dtype=int):
 [[1 0]
 [0 1]]
diag([5, 6, 7]):
 [[5 0 0]
 [0 6 0]
 [0 0 7]]
diag of a matrix: [1 4]
  • np.eye(n) and np.identity(n) both make an n x n identity matrix. eye can also make non-square ones and move the diagonal with k.
  • np.diag(list) builds a matrix with those values on the diagonal.
  • np.diag(matrix) does the opposite: it reads the diagonal of a matrix.

8. Real example: EMI and discount table

months = np.arange(1, 13)                          # months 1..12
monthly_emi = np.full(12, 4500)                    # same EMI every month
paid_so_far = monthly_emi.cumsum()                 # running total (lesson 11)
print("Month       :", months)
print("Paid so far :", paid_so_far)

discounts = np.linspace(0, 30, 7)                  # 0%, 5% ... 30%
price = 2000
print("Discount %  :", discounts)
print("Final price :", price * (1 - discounts / 100))
Output
Month       : [ 1  2  3  4  5  6  7  8  9 10 11 12]
Paid so far : [ 4500  9000 13500 18000 22500 27000 31500 36000 40500 45000 49500 54000]
Discount %  : [ 0.  5. 10. 15. 20. 25. 30.]
Final price : [2000. 1900. 1800. 1700. 1600. 1500. 1400.]
  • arange(1, 13) gives the month numbers 1 to 12.
  • full(12, 4500) makes the same EMI for each month, and cumsum() keeps a running total (lesson 11).
  • linspace(0, 30, 7) gives 7 discount levels from 0% to 30%, and one line of maths calculates all 7 final prices.

Exercises

Try these exercises on your own before moving on:

  1. Make a 4x4 array full of -1.
  2. Make the even numbers from 2 to 20 with arange.
  3. Make 9 evenly spaced values from 0 to 2 with linspace.
  4. Make a 5x5 identity matrix of integers.
  5. Make an array of zeros with the same shape as np.arange(12).reshape(3, 4).

Summary

  • np.array() turns lists into arrays; every row must have the same length.
  • zeros, ones and full create arrays of any shape; the shape is a tuple like (2, 3).
  • zeros_like and friends copy the shape and type of an existing array.
  • arange: you choose the step, stop not included. linspace: you choose the count, stop included.
  • eye / identity make identity matrices; diag builds or reads a diagonal.

Next: Lesson 03: Random Numbers and Data Types.