NumPy is the fundamental package for scientific computing with Python. It contains among other things:

  • a powerful N-dimensional array object
  • mathematical functions which operate on these arrays
  • useful linear algebra, Fourier transform, and random number capabilities

The NumPy array object is the common interface for working with typed arrays of data across a wide-variety of scientific Python packages. NumPy also features a C-API, which enables interfacing existing Fortran/C/C++ libraries with Python and NumPy.

NumPy Arrays (ndarray)

The basic type in NumPy is the N-dimensional array class, ndarray. A NumPy array represents a contiguous block of memory holding elements of the same type. The attributes of the array define how the elements are aranged in memory.

Creation


In [1]:
import numpy as np   # standard import abbreviation

In [2]:
a = np.array([1, 2, 3])  # a NumPy array of three integers
a


Out[2]:
array([1, 2, 3])

In [3]:
a.shape  # tuple representing the size of each dimension


Out[3]:
(3,)

In [4]:
a.ndim  # number of dimensions


Out[4]:
1

In [5]:
a.dtype  # Data type information


Out[5]:
dtype('int64')

In [6]:
b = np.array([1., 2., 3., 4.])  # a NumPy array of four floats

In [7]:
b.shape


Out[7]:
(4,)

In [8]:
b.dtype


Out[8]:
dtype('float64')

NumPy provides various functions for creating common arrays


In [9]:
a = np.arange(10)  # a range of values from (0) to 10
print(a)


[0 1 2 3 4 5 6 7 8 9]

In [10]:
a = np.arange(1, 10, 2, dtype='float32')
print(a)
print(a.dtype)


[ 1.  3.  5.  7.  9.]
float32

In [11]:
a = np.linspace(0, 10, 5)  # 5 linearly spaced entries from 0 to 10 
print(a)


[  0.    2.5   5.    7.5  10. ]

Array operations

Mathematical operations can be performed on NumPy arrays. The operations is applied element-by-element to the entire array.


In [12]:
a = np.array([1, 2, 3])
b = np.array([6, 7, 8])

In [13]:
a + b


Out[13]:
array([ 7,  9, 11])

In [14]:
a * b


Out[14]:
array([ 6, 14, 24])

But could that be done with lists? Yes but the syntax is not as nice.


In [15]:
a = [1, 2, 3]
b = [6, 7, 8]

In [16]:
c = [i+j for i, j in zip(a, b)]
print(c)


[7, 9, 11]

NumPy provides many mathematical functions which operate on arrays.


In [17]:
a = np.linspace(-np.pi, np.pi, 10)

In [18]:
np.sin(a)


Out[18]:
array([ -1.22464680e-16,  -6.42787610e-01,  -9.84807753e-01,
        -8.66025404e-01,  -3.42020143e-01,   3.42020143e-01,
         8.66025404e-01,   9.84807753e-01,   6.42787610e-01,
         1.22464680e-16])

In [19]:
np.cos(a)


Out[19]:
array([-1.        , -0.76604444, -0.17364818,  0.5       ,  0.93969262,
        0.93969262,  0.5       , -0.17364818, -0.76604444, -1.        ])

Multiple dimensions

NumPy arrays can also be multidimentional.


In [20]:
a = np.arange(12).reshape(3, 4)  # create a 2 dimensional array with dimensions of 3 and 4
print(a)


[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

In [21]:
a.ndim


Out[21]:
2

In [22]:
a.shape


Out[22]:
(3, 4)

In [23]:
2 * a


Out[23]:
array([[ 0,  2,  4,  6],
       [ 8, 10, 12, 14],
       [16, 18, 20, 22]])

Indexing and Slicing

Like Python lists, arrays can be indexed and sliced.


In [24]:
a = np.arange(10)

In [25]:
a[3]


Out[25]:
3

In [26]:
a[2:-2]


Out[26]:
array([2, 3, 4, 5, 6, 7])

In [27]:
a[1::2]


Out[27]:
array([1, 3, 5, 7, 9])

Multidimentional arrays can also be sliced. A comma seperates the dimensions.


In [28]:
b = np.arange(12).reshape(3, 4)
print(b)


[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

In [29]:
b[1, 2]


Out[29]:
6

In [30]:
b[2]  # select the entire second dimension


Out[30]:
array([ 8,  9, 10, 11])

In [31]:
b[1:3, :3]  # slices are also allowed


Out[31]:
array([[ 4,  5,  6],
       [ 8,  9, 10]])

In [32]:
b[:, 2]  # all elements in the first dimension


Out[32]:
array([ 2,  6, 10])

In [33]:
# ... (ellipsis) will replace one or more dimensions
b[..., 2]


Out[33]:
array([ 2,  6, 10])

Logical indexing

Logical indexing allow selecting elements from an array using an array of True and False values. Often this is array is not implicitly specified.


In [34]:
a = np.arange(5)

In [35]:
selection = np.array([True, False, False, True, True])
a[selection]


Out[35]:
array([0, 3, 4])

In [36]:
a[a>2]


Out[36]:
array([3, 4])

Masked Arrays

Masked arrays are a specialization of NumPy arrays to handle flagging elements that should be ignored. This allows for the elimination of values from computations.


In [37]:
a = np.ma.arange(12).reshape(3, 4)
print(a)


[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

In [38]:
a[2,2] = np.ma.masked
print(a)


[[0 1 2 3]
 [4 5 6 7]
 [8 9 -- 11]]

In [39]:
b = a * 2
print(b)


[[0 2 4 6]
 [8 10 12 14]
 [16 18 -- 22]]

In [40]:
# logical masking
a[a > 6] = np.ma.masked
print(a)


[[0 1 2 3]
 [4 5 6 --]
 [-- -- -- --]]

In [41]:
# unmasked an element
a[-1, -1] = 42
print(a)


[[0 1 2 3]
 [4 5 6 --]
 [-- -- -- 42]]