Q2

This question will focus entirely on NumPy arrays: vectorized programming, slicing, and broadcasting.

A

Write a function, dot, which takes two NumPy arrays and returns their dot product as a float.

Recall how a dot product works: corresponding elements of two arrays are multiplied together, then all these products are summed.

For example: if I have two NumPy arrays [1, 2, 3] and [4, 5, 6], their dot product would be (1*4) + (2*5) + (3*6), or 4 + 10 + 18, or 32.

You can use NumPy arrays, but no other NumPy functions.


In [ ]:


In [ ]:
import numpy as np
np.random.seed(57442)

x1 = np.random.random(10)
x2 = np.random.random(10)
np.testing.assert_allclose(x1.dot(x2), dot(x1, x2))

In [ ]:
import numpy as np
np.random.seed(495835)

x1 = np.random.random(100)
x2 = np.random.random(100)
np.testing.assert_allclose(x1.dot(x2), dot(x1, x2))

B

Write a function, subarray, which takes two arguments:

  • a NumPy array of data
  • a NumPy array of indices

The function should return a NumPy array that corresponds to the elements of the input array of data selected by the indices array.

For example, subarray([1, 2, 3], [2]) should return a NumPy array of [3].


In [ ]:


In [ ]:
import numpy as np
np.random.seed(5381)

x1 = np.random.random(43)
i1 = np.random.randint(0, 43, 10)
a1 = np.array([ 0.24317871,  0.16900041,  0.20687451,  0.38726974,  0.49798077,
        0.32797843,  0.18801287,  0.29021025,  0.65418547,  0.78651195])
np.testing.assert_allclose(a1, subarray(x1, i1), rtol = 1e-5)

x2 = np.random.random(74)
i2 = np.random.randint(0, 74, 5)
a2 = np.array([ 0.96372034,  0.84256813,  0.08188566,  0.71852542,  0.92384611])
np.testing.assert_allclose(a2, subarray(x2, i2), rtol = 1e-5)

C

Write a function, length, which computes the lengths of a 1-dimensional NumPy array.

Recall that the length $l$ of a vector $\vec{x}$ is defined as the square root of the sum of all the elements in the vector squared:

$$ l = \sqrt{x_1^2 + x_2^2 + ... + x_n^2} $$

Here's the rub: you should do this without any loops. Use pure vectorized programming to compute the length of an input NumPy array. Return the length (a floating point value) from the function.

You can use the np.sum() function, but no others.


In [ ]:


In [ ]:
import numpy as np
np.random.seed(84853)

x1 = np.random.random(848)
a1 = 17.118570444957424
np.testing.assert_allclose(a1, length(x1))

In [ ]:
import numpy as np
np.random.seed(596862)

x1 = np.random.random(43958)
a1 = 120.98201554071815
np.testing.assert_allclose(a1, length(x1))

D

Write a function less_than which takes two parameters:

  • a NumPy array
  • a floating-point number, the threshold

You should use a boolean mask to return only the values in the NumPy array that are less than the specified threshold value (the second parameter). No loops are allowed.

For example, less_than([1, 2, 3], 2.5) should return a NumPy array of [1, 2].


In [ ]:


In [ ]:
import numpy as np
np.random.seed(85928)

x = np.random.random((10, 20, 30))
t = 0.001
y = np.array([ 0.0005339 ,  0.00085714,  0.00091265,  0.00037283])
np.testing.assert_allclose(y, less_than(x, t))

E

Write a function greater_than which takes two parameters:

  • a NumPy array
  • a floating-point number, the threshold

You should use a boolean mask to return only the values in the NumPy array that are greater than the specified threshold value (the second parameter). No loops are allowed.

For example, greater_than([1, 2, 3], 2.5) should return a NumPy array of [3].


In [ ]:


In [ ]:
import numpy as np
np.random.seed(592582)

x = np.random.random((10, 20, 30))
t = 0.999
y = np.array([ 0.99910167,  0.99982779,  0.99982253,  0.9991043 ])
np.testing.assert_allclose(y, greater_than(x, t))

F

Write a function in_between which takes three parameters:

  • a NumPy array
  • a lower threshold, a floating point value
  • an upper threshold, a floating point value

You should use a boolean mask to return only the values in the NumPy array that are in between the two specified threshold values, lower and upper. No loops are allowed.

For example, in_between([1, 2, 3], 1, 3) should return a NumPy array of [2].

Hint: you can use your functions from Parts D and E to help!


In [ ]:


In [ ]:
import numpy as np
np.random.seed(7472)

x = np.random.random((10, 20, 30))
lo = 0.499
hi = 0.501
y = np.array([ 0.50019884,  0.50039172,  0.500711  ,  0.49983418,  0.49942259,
        0.4994417 ,  0.49979261,  0.50029046,  0.5008376 ,  0.49985266,
        0.50015914,  0.50068227,  0.50060399,  0.49968918,  0.50091042,
        0.50063015,  0.50050032])
np.testing.assert_allclose(y, in_between(x, lo, hi))

In [ ]:
import numpy as np
np.random.seed(14985)

x = np.random.random((30, 40, 50))
lo = 0.49999
hi = 0.50001
y = np.array([ 0.50000714,  0.49999045])
np.testing.assert_allclose(y, in_between(x, lo, hi))

G

Write a function, not_in_between, which takes three parameters:

  • a NumPy array
  • a lower threshold, a floating point value
  • an upper threshold, a floating point value

You should use a boolean mask to return only the values in the NumPy array that are NOT in between the two specified threshold values, lower and upper. No loops are allowed.

For example, in_between([1, 2, 3, 4], 1, 3) should return a NumPy array of [4].

Hint: you can use your functions from Parts D and E to help!


In [ ]:


In [ ]:
import numpy as np
np.random.seed(475185)

x = np.random.random((10, 20, 30))
lo = 0.001
hi = 0.999
y = np.array([  9.52511605e-04,   8.62993716e-04,   3.70243252e-04,
         9.99945849e-01,   7.21751759e-04,   9.36931041e-04,
         5.10792605e-04,   6.44911672e-04])
np.testing.assert_allclose(y, not_in_between(x, lo, hi))

In [ ]:
import numpy as np
np.random.seed(51954)

x = np.random.random((30, 40, 50))
lo = 0.00001
hi = 0.99999
y = np.array([  8.46159001e-06,   9.99998669e-01,   9.99993873e-01,
         5.58488698e-06,   9.99993348e-01])
np.testing.assert_allclose(y, not_in_between(x, lo, hi))

H

Write a function, reverse_array, which takes one parameter:

  • a 1D NumPy array of data

This function uses fancy indexing to reverse the ordering of the elements in the input array, and returns the reversed array. You cannot use the [::-1] notation, nor the built-in reversed method, or any other Python function or loops. You can use the list(), range(), and np.arange() functions, however, and only some or all of those (but again, no loops!).

You must construct a list of indexes and use NumPy fancy indexing to reverse the ordering of the elements in the input list, then return the reversed list.


In [ ]:


In [ ]:
import numpy as np
np.random.seed(5748)

x1 = np.random.random(75)
y1 = x1[::-1]  # Sorry, you're not allowed to do this!
np.testing.assert_allclose(y1, reverse_array(x1))

x2 = np.random.random(581)
y2 = x2[::-1]  # Sorry, you're not allowed to do this!
np.testing.assert_allclose(y2, reverse_array(x2))