Standard matrix notation is $A_{i,j}$, where i and j are the row and column numbers, respectively.
Read $A_{i,j}$ as "A-sub-i-sub-j" or "A-sub-i-j". Commas are often not used in the subscripts or have different meanings.
In standard mathematics, the indexing starts with 1.
In Python, the indexing starts with 0.
The shape of an array is a $d$-vector (or 1-D array) that holds the number of elements in each dimension. $d$ represents the dimensionality of the array.
E.g., the shape of a $A_{i,j,k,l}$ is ($n_i$, $n_j$, $n_k$, $n_l$), where n denotes the number of elements in dimensions $i$, $j$, $k$, and $l$.
A 2-D array is a matrix, and is analogous to an array of arrays, though each element of an array must have the same data type.
with wavelength in meters, c = 3.00e8 m/s, and frequency in Hz.
We will convert wavelengths of 1 mm to 3 mm to frequencies, bracketing the peak in the cosmic microwave background radiation.
In [ ]:
import numpy as np
In [143]:
from scipy.constants import c, G, h
In [151]:
# Create a wavelength array (in mm):
waves = np.linspace(1.0, 3.0, 21)
In [152]:
print(waves.max())
waves
Out[152]:
In [154]:
# Now, convert to frequency
# (note conversion from mm to m):
freqs = c / (waves / 1e3)
freqs
Out[154]:
In [155]:
# Make a table & print (zip pairs up wave and freq
# into a list of tuples):
table = [[wave, freq] for wave, freq in zip(waves, freqs)]
for row in table:
print(row)
In [159]:
print(np.array(table))
In [160]:
# Just for review:
print(list(zip(waves, freqs)))
In [170]:
table = np.array([waves, freqs])
table
Out[170]:
In [171]:
table.transpose()
Out[171]:
In [172]:
# let's just work with the transpose
table = table.T
In [169]:
table.shape
Out[169]:
In [173]:
table[20][0]
Out[173]:
In [174]:
table[20,0]
Out[174]:
In [175]:
l = list(table)
print(l[20][0])
l[20,0]
In [177]:
table.shape
Out[177]:
In [178]:
for index1 in range(table.shape[0]):
# Q. What is table.shape[0]?
for index2 in range(table.shape[1]):
print('table[{}, {}] = {:g}'.format(index1, index2,
table[index1, index2]))
# Q. What will this loop print?
When you just loop over the elements of an array, you get rows:
In [179]:
table.shape[0]
Out[179]:
In [180]:
for row in table: # don't be fooled, it's not my naming of the looper that does that!
print(row)
In [181]:
for idontknowwhat in table:
print(idontknowwhat)
This could also be done with one loop using numpy's ndenumerate.
ndenumerate will enumerate the rows and columns of the array:
In [182]:
for index_tuple, value in np.ndenumerate(table):
print('index {} has value {:.2e}'.format(index_tuple, value))
In [183]:
print(table.shape)
print(type(table.shape))
In [184]:
table.shape[0]
Out[184]:
In [185]:
table.shape[1]
Out[185]:
Arrays can be sliced analogously to lists.
But we already saw, there's more indexing posssibilities on top with numpy.
In [186]:
table[0]
Out[186]:
In [187]:
table[:, 0]
Out[187]:
In [188]:
# Note that this is different.
# Q. What is this?
table[:][0]
Out[188]:
In [189]:
# This will print the second column:
table[:, 1]
Out[189]:
In [191]:
# To get the first five rows of the table:
print(table[:5, :])
print()
# Same as:
print(table[:5])
Numpy also has a multi-dimensional lazy indexing trick under its sleeve:
In [192]:
ndarray = np.zeros(2,3,4) # will fail. Why? Hint: Look at error message
In [194]:
ndarray = np.zeros((2,3,4))
In [195]:
ndarray = np.arange(2*3*4).reshape((2,3,4)) # will fail. Why?
In [196]:
ndarray
Out[196]:
In [198]:
ndarray[:, :, 0]
Out[198]:
In [199]:
ndarray[..., 0]
Out[199]:
For an array $A$ of any rank, $f(A)$ means applying the function $f$ to each element of $A$.
In [204]:
xArray1 = np.array([1, 2, 3], float)
xArray1
Out[204]:
In [205]:
xArray1.T
Out[205]:
In [201]:
xMatrix = np.matrix(xArray1)
print(type(xMatrix))
xMatrix
Out[201]:
In [206]:
xMatrix.shape
Out[206]:
In [207]:
xMatrix2 = xMatrix.transpose()
xMatrix2
Out[207]:
In [208]:
# Or
xMatrix.T
Out[208]:
In [210]:
iMatrix = np.eye(3) # or np.identity
iMatrix
Out[210]:
In [211]:
# And
iMatrix2 = np.mat(iMatrix) # 'mat' short for 'matrix'
iMatrix2
Out[211]:
In [214]:
# Array multiplication.
# Reminder of xMatrix?
xMatrix
Out[214]:
In [215]:
# Multiplication of any matrix by the identity matrix
# yields that matrix:
xMatrix * iMatrix
Out[215]:
In [216]:
# Reminder of xMatrix2:
xMatrix2
Out[216]:
In [217]:
xMatrix2 = iMatrix * xMatrix2
xMatrix2
Out[217]:
In [219]:
xMatrix * xMatrix2
Out[219]:
In [220]:
np.dot(xMatrix, xMatrix2)
Out[220]:
In [221]:
xMatrix
Out[221]:
In [222]:
xMatrix2
Out[222]:
In [223]:
xArray = np.array(xMatrix)
xArray2 = np.array(xMatrix2)
xArray * xArray2
Out[223]:
In [224]:
xMatrix.shape, xMatrix2.shape
Out[224]:
In [225]:
xArray.shape
Out[225]:
In [226]:
np.array(xMatrix) * np.array(xMatrix2).T
Out[226]:
In [ ]: