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)

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

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 "signiﬁcant 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) beneﬁt 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 “ﬁrst”.

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]])

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