Using numpy

In [1]:
import itertools as it
import numpy as np

Basic array properties

In [2]:
x = np.random.normal(0, 1, (3,3))
In [3]:
x
Out[3]:
array([[ 0.0512308 , -0.71167095,  1.33249074],
       [ 1.09373726, -0.95574896,  0.74410462],
       [-0.15179047,  0.59365203, -0.47439611]])
In [4]:
x.shape
Out[4]:
(3, 3)
In [5]:
x.dtype
Out[5]:
dtype('float64')

Creation of arrays

In [6]:
np.array([1,2,3])
Out[6]:
array([1, 2, 3])
In [7]:
np.array([[1,2,3],[4,5,6]], dtype='float')
Out[7]:
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
In [8]:
np.zeros((2,3))
Out[8]:
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
In [9]:
np.ones((2,3))
Out[9]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [10]:
np.empty((2, 3))
Out[10]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [11]:
np.eye(3)
Out[11]:
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
In [12]:
np.eye(3, k=1)
Out[12]:
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  0.,  0.]])
In [13]:
np.eye(3, k=-1)
Out[13]:
array([[ 0.,  0.,  0.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])
In [14]:
np.diag([2,3,4])
Out[14]:
array([[2, 0, 0],
       [0, 3, 0],
       [0, 0, 4]])
In [15]:
A = np.arange(10)
In [16]:
A
Out[16]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [17]:
np.linspace(0, 1, 5)
Out[17]:
array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ])
In [18]:
np.logspace(0, 4, 5)
Out[18]:
array([  1.00000000e+00,   1.00000000e+01,   1.00000000e+02,
         1.00000000e+03,   1.00000000e+04])
In [19]:
np.zeros_like(A)
Out[19]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
In [20]:
np.ones_like(A)
Out[20]:
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
In [21]:
np.empty_like(A)
Out[21]:
array([-8070450532247928832, -8070450532247928832,                   30,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0])
In [22]:
np.fromiter(it.cycle([1,2,3]), dtype='float', count=10)
Out[22]:
array([ 1.,  2.,  3.,  1.,  2.,  3.,  1.,  2.,  3.,  1.])
In [23]:
def fib():
    a, b = 0, 1
    while True:
        yield b
        a, b = b, a+b
In [24]:
np.fromiter(fib(), dtype='int', count=10)
Out[24]:
array([ 1,  1,  2,  3,  5,  8, 13, 21, 34, 55])
In [25]:
np.fromfunction(lambda i, j: i-2 + j-2, shape=(5,5), dtype='int')
Out[25]:
array([[-4, -3, -2, -1,  0],
       [-3, -2, -1,  0,  1],
       [-2, -1,  0,  1,  2],
       [-1,  0,  1,  2,  3],
       [ 0,  1,  2,  3,  4]])
In [26]:
np.fromstring('1-2-3', dtype='int', sep='-')
Out[26]:
array([1, 2, 3])
In [27]:
%%file christmas.txt
4 Calling Birds
5 Gold Rings
6 Geese a-Laying
7 Swans a-Swimming
8 Maids a-Milking
9 Ladies Dancing
10 Lords a-Leaping
11 Pipers Piping
12 Drummers Drumming
Overwriting christmas.txt
In [28]:
pattern = r'(\d+)\s+(.*)'
swag = np.fromregex('christmas.txt', pattern, [('num', np.int64), ('gift', object)])
In [29]:
swag[-1]
Out[29]:
(12, b'Drummers Drumming')
In [30]:
swag['num']
Out[30]:
array([ 4,  5,  6,  7,  8,  9, 10, 11, 12])
In [31]:
swag['gift']
Out[31]:
array([b'Calling Birds', b'Gold Rings', b'Geese a-Laying',
       b'Swans a-Swimming', b'Maids a-Milking', b'Ladies Dancing',
       b'Lords a-Leaping', b'Pipers Piping', b'Drummers Drumming'], dtype=object)

Indexing

In [32]:
x
Out[32]:
array([[ 0.0512308 , -0.71167095,  1.33249074],
       [ 1.09373726, -0.95574896,  0.74410462],
       [-0.15179047,  0.59365203, -0.47439611]])
In [33]:
x[0]
Out[33]:
array([ 0.0512308 , -0.71167095,  1.33249074])
In [34]:
x[-1]
Out[34]:
array([-0.15179047,  0.59365203, -0.47439611])
In [35]:
x[:,0]
Out[35]:
array([ 0.0512308 ,  1.09373726, -0.15179047])
In [36]:
x[:2, 1:]
Out[36]:
array([[-0.71167095,  1.33249074],
       [-0.95574896,  0.74410462]])
In [37]:
x[::2]
Out[37]:
array([[ 0.0512308 , -0.71167095,  1.33249074],
       [-0.15179047,  0.59365203, -0.47439611]])
In [38]:
x[::2, ::2]
Out[38]:
array([[ 0.0512308 ,  1.33249074],
       [-0.15179047, -0.47439611]])
In [39]:
x[::-1]
Out[39]:
array([[-0.15179047,  0.59365203, -0.47439611],
       [ 1.09373726, -0.95574896,  0.74410462],
       [ 0.0512308 , -0.71167095,  1.33249074]])
In [40]:
x[:, ::-1]
Out[40]:
array([[ 1.33249074, -0.71167095,  0.0512308 ],
       [ 0.74410462, -0.95574896,  1.09373726],
       [-0.47439611,  0.59365203, -0.15179047]])
In [41]:
x[[0,2],:]
Out[41]:
array([[ 0.0512308 , -0.71167095,  1.33249074],
       [-0.15179047,  0.59365203, -0.47439611]])
In [42]:
x[:, [0,2]]
Out[42]:
array([[ 0.0512308 ,  1.33249074],
       [ 1.09373726,  0.74410462],
       [-0.15179047, -0.47439611]])
In [43]:
x[[0,2], [0,2]]
Out[43]:
array([ 0.0512308 , -0.47439611])
In [44]:
x[np.ix_([0,2], [0,2])]
Out[44]:
array([[ 0.0512308 ,  1.33249074],
       [-0.15179047, -0.47439611]])
In [45]:
np.where(x > 0.5, x, 0)
Out[45]:
array([[ 0.        ,  0.        ,  1.33249074],
       [ 1.09373726,  0.        ,  0.74410462],
       [ 0.        ,  0.59365203,  0.        ]])

Strides

In [46]:
x = np.arange(4, dtype=np.int8)
In [47]:
x.strides
Out[47]:
(1,)
In [48]:
x = np.arange(4, dtype=np.int16)
In [49]:
x.strides
Out[49]:
(2,)
In [50]:
x = np.arange(4, dtype=int)
In [51]:
x.strides
Out[51]:
(8,)
In [52]:
x
Out[52]:
array([0, 1, 2, 3])
In [53]:
np.lib.stride_tricks.as_strided(x, shape=(2,), strides=(16,))
Out[53]:
array([0, 2])
In [54]:
np.lib.stride_tricks.as_strided(x, shape=(4,4), strides=(0,8))
Out[54]:
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3]])

Vectorization and ufuncs

In [55]:
x = np.arange(1,11, dtype='int')
In [56]:
x
Out[56]:
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
In [57]:
x + 1
Out[57]:
array([ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [58]:
x + x
Out[58]:
array([ 2,  4,  6,  8, 10, 12, 14, 16, 18, 20])
In [59]:
x**2
Out[59]:
array([  1,   4,   9,  16,  25,  36,  49,  64,  81, 100])
In [60]:
x.cumsum()
Out[60]:
array([ 1,  3,  6, 10, 15, 21, 28, 36, 45, 55])
In [61]:
np.log(x)
Out[61]:
array([ 0.        ,  0.69314718,  1.09861229,  1.38629436,  1.60943791,
        1.79175947,  1.94591015,  2.07944154,  2.19722458,  2.30258509])
In [62]:
np.log10(x)
Out[62]:
array([ 0.        ,  0.30103   ,  0.47712125,  0.60205999,  0.69897   ,
        0.77815125,  0.84509804,  0.90308999,  0.95424251,  1.        ])
In [63]:
np.exp2(x)
Out[63]:
array([    2.,     4.,     8.,    16.,    32.,    64.,   128.,   256.,
         512.,  1024.])
In [64]:
np.expm1(np.log1p(x))
Out[64]:
array([  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.])
In [65]:
np.clip(x, 3, 8)
Out[65]:
array([3, 3, 3, 4, 5, 6, 7, 8, 8, 8])

We can pseudo-vectorize custom functions with the vectorize decorator.

Note: This runs at the speed of a for loop.

In [66]:
myfunc = np.vectorize(lambda x: x + 10)
In [67]:
myfunc(x)
Out[67]:
array([11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
In [68]:
%timeit -n 1000 myfunc(x)
33.1 µs ± 1.08 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [69]:
%timeit -n 1000 x + 10
1.46 µs ± 482 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Reshaping

In [70]:
x
Out[70]:
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
In [71]:
x.reshape((2,5))
Out[71]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [72]:
x.reshape((5,-1))
Out[72]:
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])
In [73]:
x.reshape((-1,5))
Out[73]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [74]:
x.reshape((10,-1))
Out[74]:
array([[ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5],
       [ 6],
       [ 7],
       [ 8],
       [ 9],
       [10]])
In [75]:
y = np.arange(16).reshape((4,4))
In [76]:
y
Out[76]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
In [77]:
y.ravel()
Out[77]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])
In [78]:
y.ravel(order='F')
Out[78]:
array([ 0,  4,  8, 12,  1,  5,  9, 13,  2,  6, 10, 14,  3,  7, 11, 15])
In [79]:
z = np.ones((1,5,1), 'int')
In [80]:
z
Out[80]:
array([[[1],
        [1],
        [1],
        [1],
        [1]]])
In [81]:
z.shape
Out[81]:
(1, 5, 1)
In [82]:
z.squeeze()
Out[82]:
array([1, 1, 1, 1, 1])
In [83]:
z.squeeze().shape
Out[83]:
(5,)

Broadcasting

In [84]:
y = np.arange(12).reshape((3,4))
In [85]:
y
Out[85]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [86]:
y + 1
Out[86]:
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
In [87]:
y + 3*y
Out[87]:
array([[ 0,  4,  8, 12],
       [16, 20, 24, 28],
       [32, 36, 40, 44]])
In [88]:
c = np.arange(4)
In [89]:
y.shape
Out[89]:
(3, 4)
In [90]:
c.shape
Out[90]:
(4,)
In [91]:
y + c
Out[91]:
array([[ 0,  2,  4,  6],
       [ 4,  6,  8, 10],
       [ 8, 10, 12, 14]])
In [92]:
r = np.arange(3)
In [93]:
r.shape
Out[93]:
(3,)
In [94]:
r[:, None].shape
Out[94]:
(3, 1)
In [95]:
y + r[:, None]
Out[95]:
array([[ 0,  1,  2,  3],
       [ 5,  6,  7,  8],
       [10, 11, 12, 13]])