Chapter 2: Vectors, matrices and multidimensional arrays

Robert Johansson

Source code listings for Numerical Python - A Practical Techniques Approach for Industry (ISBN 978-1-484205-54-9).

The source code listings can be downloaded from http://www.apress.com/9781484205549

In [1]:
import numpy as np

The NumPy array object

In [2]:
data = np.array([[1, 2], [3, 4], [5, 6]])
In [3]:
type(data)
Out[3]:
numpy.ndarray
In [4]:
data
Out[4]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [5]:
data.ndim
Out[5]:
2
In [6]:
data.shape
Out[6]:
(3, 2)
In [7]:
data.size
Out[7]:
6
In [8]:
data.dtype
Out[8]:
dtype('int64')
In [9]:
data.nbytes
Out[9]:
48

Data types

In [10]:
np.array([1, 2, 3], dtype=np.int)
Out[10]:
array([1, 2, 3])
In [11]:
np.array([1, 2, 3], dtype=np.float)
Out[11]:
array([ 1.,  2.,  3.])
In [12]:
np.array([1, 2, 3], dtype=np.complex)
Out[12]:
array([ 1.+0.j,  2.+0.j,  3.+0.j])
In [13]:
data = np.array([1, 2, 3], dtype=np.float)
In [14]:
data
Out[14]:
array([ 1.,  2.,  3.])
In [15]:
data.dtype
Out[15]:
dtype('float64')
In [16]:
data = np.array([1, 2, 3], dtype=np.int)
In [17]:
data.dtype
Out[17]:
dtype('int64')
In [18]:
data
Out[18]:
array([1, 2, 3])
In [19]:
data = np.array([1, 2, 3], dtype=np.float)
In [20]:
data
Out[20]:
array([ 1.,  2.,  3.])
In [21]:
data.astype(np.int)
Out[21]:
array([1, 2, 3])
In [22]:
d1 = np.array([1, 2, 3], dtype=float)
In [23]:
d2 = np.array([1, 2, 3], dtype=complex)
In [24]:
d1 + d2
Out[24]:
array([ 2.+0.j,  4.+0.j,  6.+0.j])
In [25]:
(d1 + d2).dtype
Out[25]:
dtype('complex128')
In [26]:
np.sqrt(np.array([-1, 0, 1]))
/Users/rob/miniconda/envs/py27-npm-n2/lib/python2.7/site-packages/ipykernel/__main__.py:1: RuntimeWarning: invalid value encountered in sqrt
  if __name__ == '__main__':
Out[26]:
array([ nan,   0.,   1.])
In [27]:
np.sqrt(np.array([-1, 0, 1], dtype=complex))
Out[27]:
array([ 0.+1.j,  0.+0.j,  1.+0.j])

Real and imaginary parts

In [28]:
data = np.array([1, 2, 3], dtype=complex)
In [29]:
data
Out[29]:
array([ 1.+0.j,  2.+0.j,  3.+0.j])
In [30]:
data.real
Out[30]:
array([ 1.,  2.,  3.])
In [31]:
data.imag
Out[31]:
array([ 0.,  0.,  0.])

Creating arrays

Arrays created from lists and other array-like objects

In [32]:
np.array([1, 2, 3, 4])
Out[32]:
array([1, 2, 3, 4])
In [33]:
data.ndim
Out[33]:
1
In [34]:
data.shape
Out[34]:
(3,)
In [35]:
np.array([[1, 2], [3, 4]])
Out[35]:
array([[1, 2],
       [3, 4]])
In [36]:
data.ndim
Out[36]:
1
In [37]:
data.shape
Out[37]:
(3,)

Arrays filled with constant values

In [38]:
np.zeros((2, 3))
Out[38]:
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
In [39]:
np.ones(4)
Out[39]:
array([ 1.,  1.,  1.,  1.])
In [40]:
data = np.ones(4)
In [41]:
data.dtype
Out[41]:
dtype('float64')
In [42]:
data = np.ones(4, dtype=np.int64)
In [43]:
data.dtype
Out[43]:
dtype('int64')
In [44]:
x1 = 5.4 * np.ones(10)
In [45]:
x2 = np.full(10, 5.4)
In [46]:
x1 = np.empty(5)
In [47]:
x1.fill(3.0)
In [48]:
x1
Out[48]:
array([ 3.,  3.,  3.,  3.,  3.])
In [49]:
x2 = np.full(5, 3.0)
In [50]:
x2
Out[50]:
array([ 3.,  3.,  3.,  3.,  3.])

Arrays filled with incremental sequences

In [51]:
np.arange(0.0, 10, 1)
Out[51]:
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])
In [52]:
np.linspace(0, 10, 11)
Out[52]:
array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.])

Arrays filled with logarithmic sequences

In [53]:
np.logspace(0, 2, 5)  # 5 data points between 10**0=1 to 10**2=100
Out[53]:
array([   1.        ,    3.16227766,   10.        ,   31.6227766 ,  100.        ])

Mesh-grid arrays

In [54]:
x = np.array([-1, 0, 1])
In [55]:
y = np.array([-2, 0, 2])
In [56]:
X, Y = np.meshgrid(x, y)
In [57]:
X
Out[57]:
array([[-1,  0,  1],
       [-1,  0,  1],
       [-1,  0,  1]])
In [58]:
Y
Out[58]:
array([[-2, -2, -2],
       [ 0,  0,  0],
       [ 2,  2,  2]])
In [59]:
Z = (X + Y) ** 2
In [60]:
Z
Out[60]:
array([[9, 4, 1],
       [1, 0, 1],
       [1, 4, 9]])

Creating uninitialized arrays

In [61]:
np.empty(3, dtype=np.float)
Out[61]:
array([ 0.,  0.,  0.])

Creating arrays with properties of other arrays

In [62]:
def f(x):
    y = np.ones_like(x)
    # compute with x and y
    return y

Creating matrix arrays

In [63]:
np.identity(4)
Out[63]:
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])
In [64]:
np.eye(3, k=1)
Out[64]:
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  0.,  0.]])
In [65]:
np.eye(3, k=-1)
Out[65]:
array([[ 0.,  0.,  0.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])
In [66]:
np.diag(np.arange(0, 20, 5))
Out[66]:
array([[ 0,  0,  0,  0],
       [ 0,  5,  0,  0],
       [ 0,  0, 10,  0],
       [ 0,  0,  0, 15]])

Index and slicing

One-dimensional arrays

In [67]:
a = np.arange(0, 11)
In [68]:
a
Out[68]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
In [69]:
a[0]  # the first element
Out[69]:
0
In [70]:
a[-1] # the last element
Out[70]:
10
In [71]:
a[4]  # the fifth element, at index 4
Out[71]:
4
In [72]:
a[1:-1]
Out[72]:
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
In [73]:
a[1:-1:2]
Out[73]:
array([1, 3, 5, 7, 9])
In [74]:
a[:5]
Out[74]:
array([0, 1, 2, 3, 4])
In [75]:
a[-5:]
Out[75]:
array([ 6,  7,  8,  9, 10])
In [76]:
a[::-2]
Out[76]:
array([10,  8,  6,  4,  2,  0])

Multidimensional arrays

In [77]:
f = lambda m, n: n + 10 * m
In [78]:
A = np.fromfunction(f, (6, 6), dtype=int)
In [79]:
A
Out[79]:
array([[ 0,  1,  2,  3,  4,  5],
       [10, 11, 12, 13, 14, 15],
       [20, 21, 22, 23, 24, 25],
       [30, 31, 32, 33, 34, 35],
       [40, 41, 42, 43, 44, 45],
       [50, 51, 52, 53, 54, 55]])
In [80]:
A[:, 1]  # the second column
Out[80]:
array([ 1, 11, 21, 31, 41, 51])
In [81]:
A[1, :]  # the second row
Out[81]:
array([10, 11, 12, 13, 14, 15])
In [82]:
A[:3, :3]  # upper half diagonal block matrix
Out[82]:
array([[ 0,  1,  2],
       [10, 11, 12],
       [20, 21, 22]])
In [83]:
A[3:, :3]  # lower left off-diagonal block matrix
Out[83]:
array([[30, 31, 32],
       [40, 41, 42],
       [50, 51, 52]])
In [84]:
A[::2, ::2]  # every second element starting from 0, 0
Out[84]:
array([[ 0,  2,  4],
       [20, 22, 24],
       [40, 42, 44]])
In [85]:
A[1::2, 1::3]  # every second element starting from 1, 1
Out[85]:
array([[11, 14],
       [31, 34],
       [51, 54]])

Views

In [86]:
B = A[1:5, 1:5]
In [87]:
B
Out[87]:
array([[11, 12, 13, 14],
       [21, 22, 23, 24],
       [31, 32, 33, 34],
       [41, 42, 43, 44]])
In [88]:
B[:, :] = 0
In [89]:
A
Out[89]:
array([[ 0,  1,  2,  3,  4,  5],
       [10,  0,  0,  0,  0, 15],
       [20,  0,  0,  0,  0, 25],
       [30,  0,  0,  0,  0, 35],
       [40,  0,  0,  0,  0, 45],
       [50, 51, 52, 53, 54, 55]])
In [90]:
C = B[1:3, 1:3].copy()
In [91]:
C
Out[91]:
array([[0, 0],
       [0, 0]])
In [92]:
C[:, :] = 1  # this does not affect B since C is a copy of the view B[1:3, 1:3]
In [93]:
C
Out[93]:
array([[1, 1],
       [1, 1]])
In [94]:
B
Out[94]:
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

Fancy indexing and Boolean-valued indexing

In [95]:
A = np.linspace(0, 1, 11)
In [96]:
A[np.array([0, 2, 4])]
Out[96]:
array([ 0. ,  0.2,  0.4])
In [97]:
A[[0, 2, 4]]
Out[97]:
array([ 0. ,  0.2,  0.4])
In [98]:
A > 0.5 
Out[98]:
array([False, False, False, False, False, False,  True,  True,  True,
        True,  True], dtype=bool)
In [99]:
A[A > 0.5]
Out[99]:
array([ 0.6,  0.7,  0.8,  0.9,  1. ])
In [100]:
A = np.arange(10)
In [101]:
A
Out[101]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [102]:
indices = [2, 4, 6]
In [103]:
B = A[indices]
In [104]:
B[0] = -1  # this does not affect A
In [105]:
A
Out[105]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [106]:
A[indices] = -1
In [107]:
A
Out[107]:
array([ 0,  1, -1,  3, -1,  5, -1,  7,  8,  9])
In [108]:
A = np.arange(10)
In [109]:
B = A[A > 5]
In [110]:
B[0] = -1  # this does not affect A
In [111]:
A
Out[111]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [112]:
A[A > 5] = -1
In [113]:
A
Out[113]:
array([ 0,  1,  2,  3,  4,  5, -1, -1, -1, -1])

Reshaping and resizing

In [114]:
data = np.array([[1, 2], [3, 4]])
In [115]:
np.reshape(data, (1, 4))
Out[115]:
array([[1, 2, 3, 4]])
In [116]:
data.reshape(4)
Out[116]:
array([1, 2, 3, 4])
In [117]:
data = np.array([[1, 2], [3, 4]])
In [118]:
data
Out[118]:
array([[1, 2],
       [3, 4]])
In [119]:
data.flatten()
Out[119]:
array([1, 2, 3, 4])
In [120]:
data.flatten().shape
Out[120]:
(4,)
In [121]:
data = np.arange(0, 5)
In [122]:
column = data[:, np.newaxis]
In [123]:
column
Out[123]:
array([[0],
       [1],
       [2],
       [3],
       [4]])
In [124]:
row = data[np.newaxis, :]
In [125]:
row
Out[125]:
array([[0, 1, 2, 3, 4]])
In [126]:
data = np.arange(5)
In [127]:
data
Out[127]:
array([0, 1, 2, 3, 4])
In [128]:
np.vstack((data, data, data))
Out[128]:
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])
In [129]:
data = np.arange(5)
In [130]:
data
Out[130]:
array([0, 1, 2, 3, 4])
In [131]:
np.hstack((data, data, data))
Out[131]:
array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4])
In [132]:
data = data[:, np.newaxis]
In [133]:
np.hstack((data, data, data))
Out[133]:
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2],
       [3, 3, 3],
       [4, 4, 4]])

Vectorized expressions

Arithmetic operations

In [134]:
x = np.array([[1, 2], [3, 4]]) 
In [135]:
y = np.array([[5, 6], [7, 8]])
In [136]:
x + y
Out[136]:
array([[ 6,  8],
       [10, 12]])
In [137]:
y - x
Out[137]:
array([[4, 4],
       [4, 4]])
In [138]:
x * y
Out[138]:
array([[ 5, 12],
       [21, 32]])
In [139]:
y / x
Out[139]:
array([[5, 3],
       [2, 2]])
In [140]:
x * 2
Out[140]:
array([[2, 4],
       [6, 8]])
In [141]:
2 ** x
Out[141]:
array([[ 2,  4],
       [ 8, 16]])
In [142]:
y / 2
Out[142]:
array([[2, 3],
       [3, 4]])
In [143]:
(y / 2).dtype
Out[143]:
dtype('int64')
In [144]:
x = np.array([1, 2, 3, 4]).reshape(2,2)
In [145]:
z = np.array([1, 2, 3, 4])
In [146]:
x / z
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-146-b88ced08eb6a> in <module>()
----> 1 x / z

ValueError: operands could not be broadcast together with shapes (2,2) (4,) 
In [147]:
z = np.array([[2, 4]])
In [148]:
z
Out[148]:
array([[2, 4]])
In [149]:
z.shape
Out[149]:
(1, 2)
In [150]:
x / z
Out[150]:
array([[0, 0],
       [1, 1]])
In [151]:
zz = np.concatenate([z, z], axis=0)
In [152]:
zz
Out[152]:
array([[2, 4],
       [2, 4]])
In [153]:
x / zz
Out[153]:
array([[0, 0],
       [1, 1]])
In [154]:
z = np.array([[2], [4]])
In [155]:
z.shape
Out[155]:
(2, 1)
In [156]:
x / z
Out[156]:
array([[0, 1],
       [0, 1]])
In [157]:
zz = np.concatenate([z, z], axis=1)
In [158]:
zz
Out[158]:
array([[2, 2],
       [4, 4]])
In [159]:
x / zz
Out[159]:
array([[0, 1],
       [0, 1]])
In [160]:
x = np.array([[1, 3], [2, 4]])
x = x + y
x
Out[160]:
array([[ 6,  9],
       [ 9, 12]])
In [161]:
x = np.array([[1, 3], [2, 4]])
x += y
x
Out[161]:
array([[ 6,  9],
       [ 9, 12]])

Elementwise functions

In [162]:
x = np.linspace(-1, 1, 11)
In [163]:
x
Out[163]:
array([-1. , -0.8, -0.6, -0.4, -0.2,  0. ,  0.2,  0.4,  0.6,  0.8,  1. ])
In [164]:
y = np.sin(np.pi * x)
In [165]:
np.round(y, decimals=4)
Out[165]:
array([-0.    , -0.5878, -0.9511, -0.9511, -0.5878,  0.    ,  0.5878,
        0.9511,  0.9511,  0.5878,  0.    ])
In [166]:
np.add(np.sin(x) ** 2, np.cos(x) ** 2)
Out[166]:
array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])
In [167]:
np.sin(x) ** 2 + np.cos(x) ** 2
Out[167]:
array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])
In [168]:
def heaviside(x):
    return 1 if x > 0 else 0
In [169]:
heaviside(-1)
Out[169]:
0
In [170]:
heaviside(1.5)
Out[170]:
1
In [171]:
x = np.linspace(-5, 5, 11)
In [172]:
heaviside(x)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-172-fe9fb94bcf99> in <module>()
----> 1 heaviside(x)

<ipython-input-168-01b8e2f570bc> in heaviside(x)
      1 def heaviside(x):
----> 2     return 1 if x > 0 else 0

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [173]:
heaviside = np.vectorize(heaviside)
In [174]:
heaviside(x)
Out[174]:
array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
In [175]:
def heaviside(x):
    return 1.0 * (x > 0)

Aggregate functions

In [176]:
data = np.random.normal(size=(15,15))
In [177]:
np.mean(data)
Out[177]:
0.081598599126035468
In [178]:
data.mean()
Out[178]:
0.081598599126035468
In [179]:
data = np.random.normal(size=(5, 10, 15))
In [180]:
data.sum(axis=0).shape
Out[180]:
(10, 15)
In [181]:
data.sum(axis=(0, 2)).shape
Out[181]:
(10,)
In [182]:
data.sum()
Out[182]:
-11.37821321738001
In [183]:
data = np.arange(1,10).reshape(3,3)
In [184]:
data
Out[184]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
In [185]:
data.sum()
Out[185]:
45
In [186]:
data.sum(axis=0)
Out[186]:
array([12, 15, 18])
In [187]:
data.sum(axis=1)
Out[187]:
array([ 6, 15, 24])

Boolean arrays and conditional expressions

In [188]:
a = np.array([1, 2, 3, 4])
In [189]:
b = np.array([4, 3, 2, 1])
In [190]:
a < b
Out[190]:
array([ True,  True, False, False], dtype=bool)
In [191]:
np.all(a < b)
Out[191]:
False
In [192]:
np.any(a < b)
Out[192]:
True
In [193]:
if np.all(a < b):
    print("All elements in a are smaller than their corresponding element in b")
elif np.any(a < b):
    print("Some elements in a are smaller than their corresponding elemment in b")
else:
    print("All elements in b are smaller than their corresponding element in a")
Some elements in a are smaller than their corresponding elemment in b
In [194]:
x = np.array([-2, -1, 0, 1, 2])
In [195]:
x > 0
Out[195]:
array([False, False, False,  True,  True], dtype=bool)
In [196]:
1 * (x > 0)
Out[196]:
array([0, 0, 0, 1, 1])
In [197]:
x * (x > 0)
Out[197]:
array([0, 0, 0, 1, 2])
In [198]:
def pulse(x, position, height, width):
    return height * (x >= position) * (x <= (position + width))
In [199]:
x = np.linspace(-5, 5, 11)
In [200]:
pulse(x, position=-2, height=1, width=5)
Out[200]:
array([0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0])
In [201]:
pulse(x, position=1, height=1, width=5)
Out[201]:
array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
In [202]:
def pulse(x, position, height, width):
    return height * np.logical_and(x >= position, x <= (position + width))
In [203]:
x = np.linspace(-4, 4, 9)
In [204]:
np.where(x < 0, x**2, x**3)
Out[204]:
array([ 16.,   9.,   4.,   1.,   0.,   1.,   8.,  27.,  64.])
In [205]:
np.select([x < -1, x < 2, x >= 2],
          [x**2  , x**3 , x**4])
Out[205]:
array([  16.,    9.,    4.,   -1.,    0.,    1.,   16.,   81.,  256.])
In [206]:
np.choose([0, 0, 0, 1, 1, 1, 2, 2, 2], 
          [x**2,    x**3,    x**4])
Out[206]:
array([  16.,    9.,    4.,   -1.,    0.,    1.,   16.,   81.,  256.])
In [207]:
x[abs(x) > 2]
Out[207]:
array([-4., -3.,  3.,  4.])
In [208]:
np.nonzero(abs(x) > 2)
Out[208]:
(array([0, 1, 7, 8]),)
In [209]:
x[np.nonzero(abs(x) > 2)]
Out[209]:
array([-4., -3.,  3.,  4.])

Set operations

In [210]:
a = np.unique([1,2,3,3])
In [211]:
b = np.unique([2,3,4,4,5,6,5])
In [212]:
np.in1d(a, b)
Out[212]:
array([False,  True,  True], dtype=bool)
In [213]:
1 in a
Out[213]:
True
In [214]:
1 in b
Out[214]:
False
In [215]:
np.all(np.in1d(a, b))
Out[215]:
False
In [216]:
np.union1d(a, b)
Out[216]:
array([1, 2, 3, 4, 5, 6])
In [217]:
np.intersect1d(a, b)
Out[217]:
array([2, 3])
In [218]:
np.setdiff1d(a, b)
Out[218]:
array([1])
In [219]:
np.setdiff1d(b, a)
Out[219]:
array([4, 5, 6])

Operations on arrays

In [220]:
data = np.arange(9).reshape(3, 3)
In [221]:
data
Out[221]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [222]:
np.transpose(data)
Out[222]:
array([[0, 3, 6],
       [1, 4, 7],
       [2, 5, 8]])
In [223]:
data = np.random.randn(1, 2, 3, 4, 5)
In [224]:
data.shape
Out[224]:
(1, 2, 3, 4, 5)
In [225]:
data.T.shape
Out[225]:
(5, 4, 3, 2, 1)

Matrix and vector operations

In [226]:
A = np.arange(1, 7).reshape(2, 3)
In [227]:
A
Out[227]:
array([[1, 2, 3],
       [4, 5, 6]])
In [228]:
B = np.arange(1, 7).reshape(3, 2)
In [229]:
B
Out[229]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [230]:
np.dot(A, B)
Out[230]:
array([[22, 28],
       [49, 64]])
In [231]:
np.dot(B, A)
Out[231]:
array([[ 9, 12, 15],
       [19, 26, 33],
       [29, 40, 51]])
In [232]:
A = np.arange(9).reshape(3, 3)
In [233]:
A
Out[233]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [234]:
x = np.arange(3)
In [235]:
x
Out[235]:
array([0, 1, 2])
In [236]:
np.dot(A, x)
Out[236]:
array([ 5, 14, 23])
In [237]:
A.dot(x)
Out[237]:
array([ 5, 14, 23])
In [238]:
A = np.random.rand(3,3)
B = np.random.rand(3,3)
In [239]:
Ap = np.dot(B, np.dot(A, np.linalg.inv(B)))
In [240]:
Ap = B.dot(A.dot(np.linalg.inv(B)))
In [241]:
A = np.matrix(A)
In [242]:
B = np.matrix(B)
In [243]:
Ap = B * A * B.I
In [244]:
A = np.asmatrix(A)
In [245]:
B = np.asmatrix(B)
In [246]:
Ap = B * A * B.I
In [247]:
Ap = np.asarray(Ap)
In [248]:
np.inner(x, x)
Out[248]:
5
In [249]:
np.dot(x, x)
Out[249]:
5
In [250]:
y = x[:, np.newaxis]
In [251]:
y
Out[251]:
array([[0],
       [1],
       [2]])
In [252]:
np.dot(y.T, y)
Out[252]:
array([[5]])
In [253]:
x = np.array([1, 2, 3])
In [254]:
np.outer(x, x) 
Out[254]:
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])
In [255]:
np.kron(x, x) 
Out[255]:
array([1, 2, 3, 2, 4, 6, 3, 6, 9])
In [256]:
np.kron(x[:, np.newaxis], x[np.newaxis, :])
Out[256]:
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])
In [257]:
np.kron(np.ones((2,2)), np.identity(2))
Out[257]:
array([[ 1.,  0.,  1.,  0.],
       [ 0.,  1.,  0.,  1.],
       [ 1.,  0.,  1.,  0.],
       [ 0.,  1.,  0.,  1.]])
In [258]:
np.kron(np.identity(2), np.ones((2,2)))
Out[258]:
array([[ 1.,  1.,  0.,  0.],
       [ 1.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  1.],
       [ 0.,  0.,  1.,  1.]])
In [259]:
x = np.array([1, 2, 3, 4])
In [260]:
y = np.array([5, 6, 7, 8])
In [261]:
np.einsum("n,n", x, y)
Out[261]:
70
In [262]:
np.inner(x, y)
Out[262]:
70
In [263]:
A = np.arange(9).reshape(3, 3)
In [264]:
B = A.T
In [265]:
np.einsum("mk,kn", A, B)
Out[265]:
array([[  5,  14,  23],
       [ 14,  50,  86],
       [ 23,  86, 149]])
In [266]:
np.alltrue(np.einsum("mk,kn", A, B) == np.dot(A, B))
Out[266]:
True

Versions

In [267]:
%reload_ext version_information
%version_information numpy
Out[267]:
SoftwareVersion
Python2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]
IPython4.0.0
OSDarwin 14.5.0 x86_64 i386 64bit
numpy1.9.2