Imports the numpy
library as the name np
. This is a very common convention.
import numpy as np
Comparing Python lists and NumPy arrays.
a_list is a Python list
a_list = [1, 2, 3, 4, 5]
print('a_list is type', type(a_list))
a_array is a NumPy array
a_array = np.array(a_list)
print('a_array is type', type(a_array))
Can create Numpy arrays from a Python list and vice-versa
b_array = np.array([3, 2, 4, 1, 5])
b_list = list(b_array)
The +
operator concatenates two lists
print('a_list + b_list =', a_list + b_list)
The +
operator performs pairwise component addition for two arrays
print('a_array + b_array =', a_array + b_array)
The +
operator can also add a scalar to an array
print('a_array + 5 =', a_array + 5)
Similarly, *
will perform pairwise component multiplication
print('a_array * b_array = ', a_array * b_array)
Remember that when applied to a list and a scaler
*
will perform multiple concatenations
print('a_list * 3 =', a_list * 3)
When applied to two lists, however, *
yields
TypeError: can't multiply sequence by non-int of type 'list'
print('a_list * b_list =', a_list * b_list)
Importing the pearsonr
method from the scipy.stats.stats
module.
scipy
builds on numpy
.
from scipy.stats.stats import pearsonr
eight lists and their correlations
a = [1, 2, 3, 4, 5] # initial list
b = [1, 2, 3, 4, 5] # identical to `a`
c = [0, 1, 2, 3, 4] # identical to `a` minus 1
d = [2, 4, 6, 8, 10] # identical to `a` * 2
e = [1, 2, 3, 5, 4] # very similar, but not identical to `a`
f = [1, 5, 4, 2, 3] # not similar to `a`
g = [5, 4, 3, 2, 1] # opposite of `a`
h = [1, 1, 1, 1, 1] # flat shape; standard deviation of `h` is 0
Correlations between a
and the other lists:
comparisons = [b, c, d, e, f, g, h]
for comparison in comparisons:
pearsonr
returns a tuple corresponding to the r and p values
corr, p = pearsonr(a, comparison)
Correlation between a
and b
, c
, and d
is 1.0 (maximal).
Correlation between a
and e
is 0.9 (high, but not maximal).
Correlation between a
and f
is 0.1, indicating almost no correlation.
Correlation between a
and g
is -1.0,indicating a maximal inverse
inverse correlation.
Correlation between a
and h
is nan
(not a number), since the
calculation of correlation involves division by the standard deviations
(which for h
is 0).
print('Correlation between', a, 'and', comparison, ':', corr)
harmonic_distance
measures the Euclidean distance between two interval
vectors. This is identical to Richard Teitelbaum's "similarity index".
You can substitute different distance measures from the
scipy.spatial.distance
module. For instance, using cityblock
distance
recreates Robert Morris' "SIM" measure.
p
and q
are lists of pitches. harmonic_distance
depends on
music21 and scipy.
Returns the harmonic distance of p
and q
interpreted as chords based on
the Euclidean distance from the scipy.spatial.distance
module. Prints an
error message and returns None
if the lists are of unequal length.
def harmonic_distance(p, q):
from music21 import chord
from scipy.spatial import distance
if len(p) != len(q):
print('lists of pitches are of unequal lengths')
return None
Using the music21
Chord
class .intervalVector
property
iv_p = chord.Chord(p).intervalVector
iv_q = chord.Chord(q).intervalVector
return distance.euclidean(iv_p, iv_q)
Using harmonic_distance
to compare the harmonic similarity of three
chords
chords = [[0, 2, 3, 7], [0, 2, 4, 6], [0, 4, 8, 11]]
print('Harmonic distances')
for i in range(2):
u = chords[i]
for j in range(i+1, 3):
v = chords[j]
print(u, '<-->', v, ':', harmonic_distance(u, v))
pyplot
is a module in matplotlib
for plotting. matplotlib depends on
numpy`. See https://matplotlib.org/api/pyplot_api.html for more details.
import matplotlib.pyplot as plt
plotting two lists on the plane
x = [1, 2, 3, 4, 5]
y = [1, 7, 4, 2, 3]
plt.plot(x, y)
plot should automatically open
plt.show()
arange
is the numpy
array equivalent of Python's built-in range
function.
x = np.arange(20)
print('x is', x)
plot f(x) = x**2
print('x squared is', x**2)
plt.plot(x, x**2)
plt.show()
plot f(x) = sin(2πx/20) using numpy
's sin
function and pi
constant
y = np.sin(x * 2 * np.pi / len(x))
plt.plot(x, y)
plt.show()