diff --git a/Numpy/Array Basics/Random Sampling/__init__.py b/Numpy/Array Basics/Random Sampling/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Numpy/Array Basics/Random Sampling/task-info.yaml b/Numpy/Array Basics/Random Sampling/task-info.yaml new file mode 100644 index 0000000..e5e97df --- /dev/null +++ b/Numpy/Array Basics/Random Sampling/task-info.yaml @@ -0,0 +1,20 @@ +type: edu +files: +- name: task.py + visible: true + placeholders: + - offset: 58 + length: 23 + placeholder_text: '# TODO' + - offset: 137 + length: 27 + placeholder_text: '# TODO' + - offset: 95 + length: 6 + placeholder_text: '# TODO' +- name: tests/test_task.py + visible: false +- name: __init__.py + visible: false +- name: tests/__init__.py + visible: false diff --git a/Numpy/Array Basics/Random Sampling/task.md b/Numpy/Array Basics/Random Sampling/task.md new file mode 100644 index 0000000..90a095f --- /dev/null +++ b/Numpy/Array Basics/Random Sampling/task.md @@ -0,0 +1,65 @@ +## Random Sampling + +Sometimes you might need to fill an array with random numbers or sample them from +different statistical distributions. +Numpy's `random` module allows you to do this. It is a suite of functions based on +pseudorandom number generation. It is called pseudorandom because "random" means something that +can not be predicted logically, and if a program generates a "random" number +it can be predicted, thus it is not truly random. + +The function `numpy.random.random` returns random floats in the half-open interval `[0.0, 1.0)`: + +```python +a = np.random.random(5) +print(a) +``` +Output: +```text +[0.73719247 0.38265166 0.48330973 0.27551432 0.88136674] +``` + +### Random Generator +Call [`default_rng`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng) +to get a new instance of a [`Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator), +then call its methods to obtain samples from different distributions. +```python +rng = np.random.default_rng() +a = rng.integers(1000) # Randomly pick one integer from 0 to 1000 +print(a) +``` +Output: +```text +346 +``` +`random.Generator.integers` returns random integers from a half-open interval: low (inclusive) to high (exclusive), +or if you specify `endpoint=True`, then the interval is closed: low (inclusive) to high (inclusive). +Integers are returned from the "discrete uniform" distribution. + +Print 10 random integers from the interval `[0, 2)`: + +```python +print(rng.integers(2, size=10)) +``` +Output: +```text +[1 1 0 1 0 0 0 1 0 0] +``` +Generate a 2 x 4 array of integers between `0` and `4`, inclusive: +```python +print(rng.integers(4, size=(2, 4), endpoint=True)) +``` +Equivalent to: +```python +print(rng.integers(5, size=(2, 4))) +``` +Output: +```text +[[1 2 0 3] + [4 2 4 3]] +``` + +### Task +Using the function [`numpy.random.Generator.normal`](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.normal.html?highlight=random%20normal#numpy.random.Generator.normal), +draw 1000 samples from the normal distribution with mean equal to `1` and standard deviation equal to `0.5`. +You can visualize your sample and make sure the mean and variance are ok by running the script – we predefined the +code for that in the `if __name__ == '__main__':` block. \ No newline at end of file diff --git a/Numpy/Array Basics/Random Sampling/task.py b/Numpy/Array Basics/Random Sampling/task.py new file mode 100644 index 0000000..d670f95 --- /dev/null +++ b/Numpy/Array Basics/Random Sampling/task.py @@ -0,0 +1,20 @@ +import numpy as np +import matplotlib.pyplot as plt + +rng = np.random.default_rng() + +mu, sigma = 1, 0.5 # Mean and standard deviation +s = rng.normal(mu, sigma, 1000) + + +if __name__ == '__main__': + # Verify the mean and the variance: + print(abs(mu - np.mean(s))) # Difference should be close to 0.0 + print(abs(sigma - np.std(s, ddof=1))) # Difference should be close to 0.0 + + count, bins, ignored = plt.hist(s, 30, density=True) + plt.plot(bins, 1 / (sigma * np.sqrt(2 * np.pi)) * + np.exp(- (bins - mu) ** 2 / (2 * sigma ** 2)), + linewidth=2, color='r') + plt.show() + diff --git a/Numpy/Array Basics/Random Sampling/tests/__init__.py b/Numpy/Array Basics/Random Sampling/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Numpy/Array Basics/Random Sampling/tests/test_task.py b/Numpy/Array Basics/Random Sampling/tests/test_task.py new file mode 100644 index 0000000..dbdb951 --- /dev/null +++ b/Numpy/Array Basics/Random Sampling/tests/test_task.py @@ -0,0 +1,12 @@ +import unittest +import numpy as np + +from task import * + + +class TestCase(unittest.TestCase): + def test_normal(self): + self.assertEqual(s.shape, (1000,), msg="Draw 1000 samples") + self.assertEqual(round(abs(mu - np.mean(s)), 1), 0.0, msg="Mean should be close to 0.0") + self.assertEqual(round(abs(sigma - np.std(s, ddof=1)), 1), 0.0, msg="Variance should be close to 0.0") + diff --git a/Numpy/Array Basics/Reshape/__init__.py b/Numpy/Array Basics/Reshape/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Numpy/Array Basics/Reshape/task-info.yaml b/Numpy/Array Basics/Reshape/task-info.yaml new file mode 100644 index 0000000..95d019f --- /dev/null +++ b/Numpy/Array Basics/Reshape/task-info.yaml @@ -0,0 +1,17 @@ +type: edu +files: +- name: task.py + visible: true + placeholders: + - offset: 24 + length: 20 + placeholder_text: '# TODO' + - offset: 49 + length: 15 + placeholder_text: '# TODO' +- name: tests/test_task.py + visible: false +- name: __init__.py + visible: false +- name: tests/__init__.py + visible: false diff --git a/Numpy/Array Basics/Reshape/task.md b/Numpy/Array Basics/Reshape/task.md new file mode 100644 index 0000000..ea7fc90 --- /dev/null +++ b/Numpy/Array Basics/Reshape/task.md @@ -0,0 +1,49 @@ +## Reshape + +Reshaping means changing the `shape` of an array without changing its data. +As we mentioned earlier, the `shape` of an array is the number of elements in each dimension. +By reshaping we can add or remove dimensions or change the number of elements in each dimension. + +The function [`numpy.reshape`](https://numpy.org/doc/stable/reference/generated/numpy.reshape.html#numpy.reshape) +is used for reshaping, and it accepts three arguments: + +- The array to be reshaped. +- The new shape as an `int` or tuple of `int`s. +- An optional argument `order`, which defines the order in which the elements are read and placed into the reshaped array. + +### Examples +1. Reshape 1D array into a 2D array: +```python +a = np.arange(10) +print(np.reshape(a, (2, 5))) +``` +Output: +```text +[[0 1 2 3 4] + [5 6 7 8 9]] +``` +2. Reshape a 2D array into a 1D array: +```python +a = np.array([[1, 2, 3], [4, 5, 6]]) +print(np.reshape(a, 6)) +``` +Output: +```text +[1 2 3 4 5 6] +``` + +The latter can also be achieved by using `numpy.ndarray.flatten`: +```python +a = np.array([[1, 2, 3], [4, 5, 6]]) +print(a.flatten()) +``` +Output: +```text +[1 2 3 4 5 6] +``` + +### Task +1. Create an array `a` of integers in the interval from `12` to `30` with step `3`. +2. Reshape it so that it has 2 rows and 3 columns. + +
arange function.