In [1]:
import numpy as np
In [2]:
a = np.arange(5)
a
Out[2]:
array([0, 1, 2, 3, 4])
In [3]:
print(a*2)
print(a+3)
print(a-2)
[0 2 4 6 8]
[3 4 5 6 7]
[-2 -1  0  1  2]
In [4]:
b = np.ones(5)
b
Out[4]:
array([ 1.,  1.,  1.,  1.,  1.])
In [5]:
print(a-b*2)
print(a+b)
[-2. -1.  0.  1.  2.]
[ 1.  2.  3.  4.  5.]
In [6]:
# these operations are faster in numpy than pure python

a = np.arange(10000)
%timeit a+2
The slowest run took 6.27 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 11.4 µs per loop
In [7]:
# in native python
a = range(10000)
%timeit [i+2 for i in a]
1000 loops, best of 3: 1.03 ms per loop

Array Multiplication

1-D array

In [8]:
a = np.random.randint(1, 10, 5)
a
Out[8]:
array([2, 8, 3, 4, 2])
In [9]:
b =np.random.randint(1, 10, 5)
b 
Out[9]:
array([6, 3, 9, 3, 4])
In [10]:
a * b  # elementwise operations
Out[10]:
array([12, 24, 27, 12,  8])

2-D array

In [11]:
a = np.random.randint(1, 10, (2,3))
a
Out[11]:
array([[9, 5, 5],
       [7, 2, 4]])
In [12]:
b = np.random.randint(1, 10, (2,3))
b
Out[12]:
array([[2, 1, 5],
       [5, 2, 7]])
In [13]:
a * b  # element wise multiplication
Out[13]:
array([[18,  5, 25],
       [35,  4, 28]])
In [14]:
# a.dot(b) this will throw an error as Matix multiplication is not possible here
In [15]:
a.dot(b.T)   # b.T will transpose the 2,3 matrix to 3,2 matrix
Out[15]:
array([[48, 90],
       [36, 67]])

Comparison

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

print(a,b)
[1 3 7 6 5] [1 2 7 8 5]
In [17]:
# Comparison
a == b
Out[17]:
array([ True, False,  True, False,  True], dtype=bool)
In [18]:
a > b
Out[18]:
array([False,  True, False, False, False], dtype=bool)

Arraywise Comparison

In [19]:
a = np.array([1,2,3,4])
b = np.array([3,4, 9, 8])
c = np.array([1,2,3,4])
In [20]:
np.array_equal(a, b)
Out[20]:
False
In [21]:
np.array_equal(a, c)
Out[21]:
True

Logical Operations

In [22]:
a = np.array([1,1,0,0], dtype='bool')
b = np.array([1,0,1,0], dtype='bool')

print(a, b)
[ True  True False False] [ True False  True False]
In [23]:
np.logical_or(a,b)
Out[23]:
array([ True,  True,  True, False], dtype=bool)
In [24]:
np.logical_and(a,b)
Out[24]:
array([ True, False, False, False], dtype=bool)

Adv mathematics func

In [25]:
a = np.array([1, 0.5, 0, 3])
a
Out[25]:
array([ 1. ,  0.5,  0. ,  3. ])
In [26]:
np.sin(a)
Out[26]:
array([ 0.84147098,  0.47942554,  0.        ,  0.14112001])
In [27]:
np.log(a)
C:\tools\Anaconda3\lib\site-packages\ipykernel\__main__.py:1: RuntimeWarning: divide by zero encountered in log
  if __name__ == '__main__':
Out[27]:
array([ 0.        , -0.69314718,        -inf,  1.09861229])
In [28]:
np.exp(a)
Out[28]:
array([  2.71828183,   1.64872127,   1.        ,  20.08553692])
In [29]:
a = np.triu(np.ones((3, 3)), 1)
a
Out[29]:
array([[ 0.,  1.,  1.],
       [ 0.,  0.,  1.],
       [ 0.,  0.,  0.]])
In [30]:
a.T  # transposition of array is just a view and stored in memory
Out[30]:
array([[ 0.,  0.,  0.],
       [ 1.,  0.,  0.],
       [ 1.,  1.,  0.]])

Counting Sums

In [31]:
x = np.array([1,2,3,4])
x.sum()
Out[31]:
10
In [32]:
x = np.array([[1,2,3],[3,4,5]])
x
Out[32]:
array([[1, 2, 3],
       [3, 4, 5]])
In [33]:
x.sum(axis=0)  # column sum
Out[33]:
array([4, 6, 8])
In [34]:
x.sum(axis=1)  # row sum
Out[34]:
array([ 6, 12])

Other functions

In [35]:
x.min()
Out[35]:
1
In [36]:
x.min(axis=1)
Out[36]:
array([1, 3])
In [37]:
x.max(axis=0)
Out[37]:
array([3, 4, 5])
In [38]:
x.argmin()  # index of min element
Out[38]:
0
In [39]:
x.argmax()  # index of max element
Out[39]:
5

Logical Operations

In [40]:
np.all([True, False, True])
Out[40]:
False
In [41]:
np.any([True, False, True])
Out[41]:
True
In [42]:
a = np.zeros((10,10))
np.any(a)
Out[42]:
False
In [43]:
np.all(a)
Out[43]:
False
In [44]:
np.all(a==0)
Out[44]:
True
In [45]:
np.any(a!=0)
Out[45]:
False

Stats

In [46]:
x = np.array([1, 2, 3, 1])
y = np.array([[1, 2, 3], [5, 6, 1]])

print(x, "\n\n",y)
[1 2 3 1] 

 [[1 2 3]
 [5 6 1]]
In [47]:
x.mean()
Out[47]:
1.75
In [48]:
np.median(x)
Out[48]:
1.5
In [49]:
np.median(y, axis=-1) # last axis
Out[49]:
array([ 2.,  5.])
In [50]:
x.std()
Out[50]:
0.82915619758884995

broadcasing

In [51]:
a = np.ones((3,4))
a
Out[51]:
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])
In [52]:
a[2:,2:]=0
a
Out[52]:
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  0.,  0.]])
In [53]:
a = np.arange(0, 40, 10)
a.shape
Out[53]:
(4,)

newaxis

In [54]:
a = a[:, np.newaxis]   # newaxis is a nice feature supported by numpy
a
Out[54]:
array([[ 0],
       [10],
       [20],
       [30]])
In [55]:
a.shape
Out[55]:
(4, 1)
In [56]:
mileposts = np.array([0, 198, 303, 736, 871, 1175, 1475, 1544,1913, 2448])
In [57]:
distance = np.abs(mileposts - mileposts[:, np.newaxis])
distance
Out[57]:
array([[   0,  198,  303,  736,  871, 1175, 1475, 1544, 1913, 2448],
       [ 198,    0,  105,  538,  673,  977, 1277, 1346, 1715, 2250],
       [ 303,  105,    0,  433,  568,  872, 1172, 1241, 1610, 2145],
       [ 736,  538,  433,    0,  135,  439,  739,  808, 1177, 1712],
       [ 871,  673,  568,  135,    0,  304,  604,  673, 1042, 1577],
       [1175,  977,  872,  439,  304,    0,  300,  369,  738, 1273],
       [1475, 1277, 1172,  739,  604,  300,    0,   69,  438,  973],
       [1544, 1346, 1241,  808,  673,  369,   69,    0,  369,  904],
       [1913, 1715, 1610, 1177, 1042,  738,  438,  369,    0,  535],
       [2448, 2250, 2145, 1712, 1577, 1273,  973,  904,  535,    0]])
In [58]:
x, y = np.arange(5), np.arange(5)[:, np.newaxis]

print(x, "\n\n", y)
[0 1 2 3 4] 

 [[0]
 [1]
 [2]
 [3]
 [4]]
In [59]:
distance = np.sqrt(x ** 2 + y ** 2)
distance
Out[59]:
array([[ 0.        ,  1.        ,  2.        ,  3.        ,  4.        ],
       [ 1.        ,  1.41421356,  2.23606798,  3.16227766,  4.12310563],
       [ 2.        ,  2.23606798,  2.82842712,  3.60555128,  4.47213595],
       [ 3.        ,  3.16227766,  3.60555128,  4.24264069,  5.        ],
       [ 4.        ,  4.12310563,  4.47213595,  5.        ,  5.65685425]])

the numpy.ogrid function allows to directly create vectors x and y of the previous example, with two "significant dimensions":

In [60]:
x, y = np.ogrid[0:5, 0:5]

print(x, "\n\n", y)
[[0]
 [1]
 [2]
 [3]
 [4]] 

 [[0 1 2 3 4]]
In [61]:
print(x.shape, y.shape)
(5, 1) (1, 5)
In [62]:
distance = np.sqrt(x ** 2 + y ** 2)
distance
Out[62]:
array([[ 0.        ,  1.        ,  2.        ,  3.        ,  4.        ],
       [ 1.        ,  1.41421356,  2.23606798,  3.16227766,  4.12310563],
       [ 2.        ,  2.23606798,  2.82842712,  3.60555128,  4.47213595],
       [ 3.        ,  3.16227766,  3.60555128,  4.24264069,  5.        ],
       [ 4.        ,  4.12310563,  4.47213595,  5.        ,  5.65685425]])

np.mgrid directly providesmatrices full of indices for cases where we can’t (or don’t want to) benefit frombroadcasting

In [63]:
x, y = np.mgrid[0:4, 0:4]
print(x, "\n\n", y)
[[0 0 0 0]
 [1 1 1 1]
 [2 2 2 2]
 [3 3 3 3]] 

 [[0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]
 [0 1 2 3]]

Flattening the array

Higher dimensions: last dimensions ravel out “first”.

In [64]:
a = np.array([[1, 2, 3], [4, 5, 6]])
a
Out[64]:
array([[1, 2, 3],
       [4, 5, 6]])
In [65]:
a.ravel()
Out[65]:
array([1, 2, 3, 4, 5, 6])
In [66]:
a.T.ravel()
Out[66]:
array([1, 4, 2, 5, 3, 6])

Reshaping

reshaping may return view or copy, so use caustiously

In [67]:
a.shape
Out[67]:
(2, 3)
In [68]:
a.ravel()
Out[68]:
array([1, 2, 3, 4, 5, 6])
In [69]:
a.ravel().reshape(3,2)
Out[69]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [70]:
a.reshape((2, -1))   # # unspecified (-1) value is inferred
Out[70]:
array([[1, 2, 3],
       [4, 5, 6]])
In [71]:
a.reshape((3, -1))
Out[71]:
array([[1, 2],
       [3, 4],
       [5, 6]])

Adding a dimention

In [72]:
a = np.arange(4)
a
Out[72]:
array([0, 1, 2, 3])
In [73]:
a[:, np.newaxis]
Out[73]:
array([[0],
       [1],
       [2],
       [3]])
In [74]:
a[np.newaxis,:]
Out[74]:
array([[0, 1, 2, 3]])

Dimension shuffling

In [75]:
a = np.arange(4*3*2).reshape(4, 3, 2)
a
Out[75]:
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5]],

       [[ 6,  7],
        [ 8,  9],
        [10, 11]],

       [[12, 13],
        [14, 15],
        [16, 17]],

       [[18, 19],
        [20, 21],
        [22, 23]]])
In [76]:
a.shape
Out[76]:
(4, 3, 2)
In [77]:
a[0,1,0]
Out[77]:
2
In [78]:
a.ravel().reshape(2,3,4)
Out[78]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

Resizing

In [83]:
o = np.arange(4)
o.resize((8,))
o

# It will throw an error 
# ValueError: cannot resize an array that references or is referenced
# by another array in this way.  Use the resize function
Out[83]:
array([0, 1, 2, 3, 0, 0, 0, 0])

Sorting data

In [84]:
a = np.array([[4, 3, 5], [1, 2, 1]])
a
Out[84]:
array([[4, 3, 5],
       [1, 2, 1]])
In [87]:
b = np.sort(a, axis=1)  # Sorts each row separately!
b
Out[87]:
array([[3, 4, 5],
       [1, 1, 2]])
In [89]:
a.sort(axis=1)  # inplace sort
a
Out[89]:
array([[3, 4, 5],
       [1, 1, 2]])
In [90]:
# Sorting with fancy indexing:
a = np.array([4, 3, 1, 2])
j = np.argsort(a)
j
Out[90]:
array([2, 3, 1, 0], dtype=int64)
In [91]:
a[j]
Out[91]:
array([1, 2, 3, 4])
In [93]:
# Finding minima and maxima
j_max = np.argmax(a)
j_min = np.argmin(a)

print(j_max, j_min)  # indexes
print(a[j_max], a[j_min])
0 2
4 1