Creating Arrays

In the previous section, we looked at NumPy’s basic data structure for representing arrays, the ndarray class, and we looked at the basic attributes of this class. In this section we focus on functions from the NumPy library that can be used to create ndarray instances.

NumPy provides a set of functions generate ndarrays depending on their properties and the applications they are used for. Throughout this tutorial you’ll discover that these features will be useful.

Arrays Created from Lists and Other Array-like Objects

  • Using the np.array() function, NumPy arrays can be constructed from explicit Python lists, iterable expressions and other array-like objects (such as other ndarray instances).
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
data = np.array([1, 3, 9]) # Create a one-dimensional array from a Python list
data
array([1, 3, 9])
data.ndim
1
data.shape
(3,)
data = np.array([[1, 2], [5, 7]]) # Create 2D array using nested Python lists
data
array([[1, 2],
       [5, 7]])
data.ndim
2
data.shape
(2, 2)

Arrays Filled with Constant Values

  • The functions np.zeros() and np.ones() create and return arrays filled with zeros and ones respectively.
  • They take, as first argument, an integer or a tuple that describes the number of elements along each dimension of the array
np.zeros((2, 3))
array([[0., 0., 0.],
       [0., 0., 0.]])
np.ones(5)
array([1., 1., 1., 1., 1.])
  • Like other array-generating functions, these functions also accept an optional keyword argument that specifies the data type for the elements in the array.
  • By default, the data type is float64:
data = np.ones(10)
data
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
data.dtype
dtype('float64')
data = np.ones(5, dtype=complex)
data
array([1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j])
data.dtype
dtype('complex128')
  • Arrays filled with an arbitrary constant value can be generated by first creating an array filled with ones and then multiplying the array with the desired fill value.
  • However, NumPy also provides the function np.full() that does exactly this in one step:
x = 10.5 * np.ones(5)
x
array([10.5, 10.5, 10.5, 10.5, 10.5])
y = np.full(shape=5, fill_value=10.5)
y
array([10.5, 10.5, 10.5, 10.5, 10.5])
  • An already created array can also be filled with constant values using the np.fill() function, which takes an array and a value as arguments, and set all elements in the array to the given value:
x1 = np.empty(3) # generates an array with uninitialized values, of the given size
x1
array([0.75, 0.75, 0.  ])
x1.fill(np.pi)
x1
array([3.14159265, 3.14159265, 3.14159265])

Arrays Filled with Logarithmic Sequences

The function np.logspace() is similar to np.linspace(), but the increments between the elements in the array are logarithmically distributed, and the first two arguments, for the start and end values, are the powers of the optional base keyword argument (which defaults to 10):

# Generate 5 points between 10**0= 1 and 10**2=100
np.logspace(start=0, stop=2, num=5) 
array([  1.        ,   3.16227766,  10.        ,  31.6227766 ,
       100.        ])

Meshgrid Arrays

  • Multidimensional coordinate grids can be generated using the function np.meshgrid().
  • Given two one-dimensional coordinate arrays, we can generate two-dimensional coordinate arrays using the np.meshgrid() function:
# 1-D arrays representing the coordinates of a grid
y = np.linspace(-90., 90., num=180)
x = np.linspace(-180., 180., 360)
xc, yc = np.meshgrid(x, y)
z = np.sin(xc**2 + yc**2) / np.cos(xc**2 + yc**2)
xc
array([[-180.        , -178.99721448, -177.99442897, ...,  177.99442897,
         178.99721448,  180.        ],
       [-180.        , -178.99721448, -177.99442897, ...,  177.99442897,
         178.99721448,  180.        ],
       [-180.        , -178.99721448, -177.99442897, ...,  177.99442897,
         178.99721448,  180.        ],
       ...,
       [-180.        , -178.99721448, -177.99442897, ...,  177.99442897,
         178.99721448,  180.        ],
       [-180.        , -178.99721448, -177.99442897, ...,  177.99442897,
         178.99721448,  180.        ],
       [-180.        , -178.99721448, -177.99442897, ...,  177.99442897,
         178.99721448,  180.        ]])
yc
array([[-90.        , -90.        , -90.        , ..., -90.        ,
        -90.        , -90.        ],
       [-88.99441341, -88.99441341, -88.99441341, ..., -88.99441341,
        -88.99441341, -88.99441341],
       [-87.98882682, -87.98882682, -87.98882682, ..., -87.98882682,
        -87.98882682, -87.98882682],
       ...,
       [ 87.98882682,  87.98882682,  87.98882682, ...,  87.98882682,
         87.98882682,  87.98882682],
       [ 88.99441341,  88.99441341,  88.99441341, ...,  88.99441341,
         88.99441341,  88.99441341],
       [ 90.        ,  90.        ,  90.        , ...,  90.        ,
         90.        ,  90.        ]])
z
array([[-6.26401298, -0.12722142,  0.02897983, ...,  0.02897983,
        -0.12722142, -6.26401298],
       [ 1.04103746, -1.74389138, -1.24635196, ..., -1.24635196,
        -1.74389138,  1.04103746],
       [-2.88637827,  0.04870371,  0.20706408, ...,  0.20706408,
         0.04870371, -2.88637827],
       ...,
       [-2.88637827,  0.04870371,  0.20706408, ...,  0.20706408,
         0.04870371, -2.88637827],
       [ 1.04103746, -1.74389138, -1.24635196, ..., -1.24635196,
        -1.74389138,  1.04103746],
       [-6.26401298, -0.12722142,  0.02897983, ...,  0.02897983,
        -0.12722142, -6.26401298]])
plt.contourf(x, y, z)
<matplotlib.contour.QuadContourSet at 0x11b192ba8>

png

  • It is also possible to generate higher-dimensional coordinate arrays by passing more arrays as argument to the np.meshgrid() function

Creating Uninitialized Arrays

  • To create an array of specific size and data type, but without initializing the elements of the array to any particular values, we can use the function np.empty()

  • The advantage of this function, for example, instead ofnp.zeros, is that we can avoid the initiation step. If all elements are guaranteed to be initialized later in the code, this can save a little bit of time, especially when working with large arrays:

np.empty(shape=5, dtype=np.float64)
array([2.5e-323, 3.0e-323, 3.5e-323, 4.0e-323, 4.4e-323])

NOTE:

  • There’s no guarantee that elements generated by np.empty() have any particular values. For this reason it is important that all values are explicitly assigned before the array is used; otherwise unpredictable errors are likely to arise.

Creating Arrays with Properties of Other Arrays

It is often necessary to create new arrays that share properties, such as shape and data type with another array. NumPy provides a family of functions for this purpose:

  • np.ones_like()
  • np.zeros_like()
  • np.full_like()
  • np.empty_like()

A typical use-case is a function that takes arrays of unspecified type and size as arguments and requires working with arrays of the same size and type.

data = np.array([[2, 3, 8], [6, 8, 10]], dtype=np.float32)
data
array([[ 2.,  3.,  8.],
       [ 6.,  8., 10.]], dtype=float32)
np.ones_like(data)
array([[1., 1., 1.],
       [1., 1., 1.]], dtype=float32)
np.zeros_like(data)
array([[0., 0., 0.],
       [0., 0., 0.]], dtype=float32)
fill_value = np.sin(np.deg2rad(90))
np.full_like(data, fill_value=fill_value)
array([[1., 1., 1.],
       [1., 1., 1.]], dtype=float32)

Creating Matrix Arrays

NumPy provides functions for generating commonly used matrixes. One of these functions is np.identity() which generates a square matrix with oens on the diagonal and zeros elsewhere:

np.identity(6)
array([[1., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 0., 1.]])

The similar function np.eye() generates matrices with ones on a diagonal (optionally offset):

np.eye(N=4, M=5, k=1)
array([[0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

where:

  • N: is the number of rows in the output
  • M: is the number of columns in the output
  • k: Index of the diagonal: 0 (the default) refers to the main diagonal, a positive value refers to an upper diagonal, and a negative value to a lower diagonal.a
np.eye(N=4, M=5, k=-1)
array([[0., 0., 0., 0., 0.],
       [1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.]])

To construct a matrix with an arbitrary one-dimensional array on the diagonal, we can use the np.diag() function (which also takes the optional keyword argument k to specify an offset from the diagonal) :

d = np.arange(0, 20, 4)
d
array([ 0,  4,  8, 12, 16])
np.diag(v=d, k=0)
array([[ 0,  0,  0,  0,  0],
       [ 0,  4,  0,  0,  0],
       [ 0,  0,  8,  0,  0],
       [ 0,  0,  0, 12,  0],
       [ 0,  0,  0,  0, 16]])
np.diag(v=d, k=-1)
array([[ 0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0],
       [ 0,  4,  0,  0,  0,  0],
       [ 0,  0,  8,  0,  0,  0],
       [ 0,  0,  0, 12,  0,  0],
       [ 0,  0,  0,  0, 16,  0]])
%load_ext watermark
%watermark --iversion -g -m -v -u -d
matplotlib 3.0.3
numpy      1.16.3
last updated: 2019-05-16 

CPython 3.6.7
IPython 7.5.0

compiler   : GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)
system     : Darwin
release    : 18.2.0
machine    : x86_64
processor  : i386
CPU cores  : 8
interpreter: 64bit
Git hash   : de652def25a7c27af680815143f400347196017d