In [1]:
name = '2016-02-19-numpy-arrays-basics'
title = 'Back to basics: NumPy arrays'
tags = 'numpy'
author = 'Denis Sergeev'
In [2]:
from nb_tools import connect_notebook_to_post
from IPython.core.display import HTML
html = connect_notebook_to_post(name, title, tags, author)
Today we refreshed our knowledge of python numerical arrays and their basic features.
Basic data containers in Python include
In [3]:
from IPython.display import Image
Image('https://mlpforums.com/uploads/monthly_01_2014/post-6104-0-95171600-1390631637.jpg', width=200, height=200)
Out[3]:
Lists in Python are quite general, can have arbitrary objects as elements.
Addition and scalar multiplication are defined for lists, but not what we want for numerical computation, e.g.
Addition results in concatenation
In [4]:
x = [1, 2, 3]
y = [10, 20, 30]
x + y
Out[4]:
And multiplication results in repeating:
In [5]:
x = [2, 3]
x * 3
Out[5]:
In [6]:
import numpy as np
NumPy’s main object is the homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of positive integers. In Numpy dimensions are called axes. The number of axes is rank.
Why it is useful: Memory-efficient container that provides fast numerical operations.
In [7]:
l = list(range(1000))
In [8]:
%timeit [i**2 for i in l]
In [9]:
a = np.arange(1000)
In [10]:
%timeit a**2
In [11]:
a = np.array([3, 4, 5, 6])
In [12]:
a
Out[12]:
The class is called
In [13]:
type(a)
Out[13]:
Scalar array
In [14]:
a0 = np.array(7)
In [15]:
a0.ndim
Out[15]:
In [16]:
b = np.array([[10, 20, 30], [9, 8, 7]])
In [17]:
b
Out[17]:
In [18]:
c = np.array([[[1], [2]], [[3], [4]]])
In [19]:
c.shape
Out[19]:
In [20]:
try:
a = np.array(1,2,3,4) # WRONG, throws ValueError
except ValueError as e:
print(e)
In [21]:
a = np.array([1,2,3,4]) # RIGHT
Do not use np.ndarray function to create an array
In [22]:
np.ndarray([1,2,3,4])
Out[22]:
In [23]:
np.arange(1, 9, 2) # start, end (exclusive), step
Out[23]:
In [24]:
np.linspace(0, 1, 6) # start, end, num-points
Out[24]:
In [25]:
np.logspace(-3,2,7)
Out[25]:
In [26]:
np.zeros((2, 3))
Out[26]:
In [27]:
np.ones((3, 2))
Out[27]:
In [28]:
np.empty([2,3])
Out[28]:
The function empty creates an array whose initial content is random and depends on the state of the memory. By default, the dtype of the created array is float64.
In [29]:
np.random.seed(1234)
In [30]:
np.random.rand(4) # uniform in [0, 1]
Out[30]:
In [31]:
np.random.randn(4) # Gaussian
Out[31]:
In [32]:
np.eye(3)
Out[32]:
In [33]:
np.diag(np.array([1, 2, 3, 4]))
Out[33]:
In [34]:
b
Out[34]:
In [35]:
b.ndim
Out[35]:
In [36]:
b.shape
Out[36]:
In [37]:
b.size
Out[37]:
Note that size is not equal to len(). The latter returns the length of the first dimension.
In [38]:
len(b)
Out[38]:
In [39]:
b.dtype
Out[39]:
In [40]:
a.itemsize
Out[40]:
In [41]:
b.data
Out[41]:
A common source for confusion and mistakes is that numpy arrays are mutable, meaning they can be changed after creation. Other common mutable objects are lists and dictionaries, while tuples are inmutable.
It also implies that when operating and manipulating arrays, their data is sometimes copied into a new array and sometimes not.
Create an array
In [42]:
a = np.arange(12)
a
Out[42]:
Change its 6th element
In [43]:
a[5] = 1000
In [44]:
a
Out[44]:
In [45]:
a = np.arange(6)
In [46]:
b = a
a and b are two names for the same ndarray object
In [47]:
b is a
Out[47]:
Change the shape and the 3rd element of b
In [48]:
b[2] = 999
b.shape = 3, 2
b
Out[48]:
But a is also changed!
In [49]:
a
Out[49]:
Python passes mutable objects as references, so function calls make no copy neither.
In [50]:
a = np.arange(6)
In [51]:
c = a.view()
In [52]:
c is a
Out[52]:
c is a view of the data owned by a
In [53]:
c.base is a
Out[53]:
In [54]:
c[2] = 999
a # a's data changes
Out[54]:
In [55]:
c.shape = 2,3
a.shape # a's shape doesn't change
Out[55]:
Slicing an array returns a view of it:
In [56]:
s = a[2:5]
s
Out[56]:
In [57]:
s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10
In [58]:
a
Out[58]:
In [59]:
a = np.arange(6)
Create a copy using copy() attribute
In [60]:
d = a.copy()
The copy doesn't share anything with the original array:
In [61]:
d is a
Out[61]:
In [62]:
d.base is a
Out[62]:
In [63]:
d[-1] = 1000
In [64]:
d
Out[64]:
In [65]:
a
Out[65]:
In [66]:
np.rollaxis??
In [67]:
np.*space*?
In [68]:
np.lookfor('create array')
In [69]:
HTML(html)
Out[69]: