diff --git a/10_Random_sampling.ipynb b/10_Random_sampling.ipynb new file mode 100644 index 0000000..b3fc88f --- /dev/null +++ b/10_Random_sampling.ipynb @@ -0,0 +1,301 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Random Sampling" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "__author__ = 'kyubyong. longinglove@nate.com'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simple random data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Create an array of shape (3, 2) and populate it with random samples from a uniform distribution over [0, 1)." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0.13879034, 0.71300174],\n", + " [ 0.08121322, 0.00393554],\n", + " [ 0.02349471, 0.56677474]])" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Create an array of shape (1000, 1000) and populate it with random samples from a standard normal distribution. And verify that the mean and standard deviation is close enough to 0 and 1 repectively." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-0.00110028519551\n", + "0.999683483393\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Create an array of shape (3, 2) and populate it with random integers ranging from 0 to 3 (inclusive) from a discrete uniform distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 3],\n", + " [3, 0],\n", + " [0, 0]])" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Extract 1 elements from x randomly such that each of them would be associated with probabilities .3, .5, .2. Then print the result 10 times." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5 out of 10\n", + "2 out of 10\n", + "3 out of 10\n", + "5 out of 10\n", + "2 out of 10\n", + "5 out of 10\n", + "2 out of 10\n", + "2 out of 10\n", + "2 out of 10\n", + "5 out of 10\n" + ] + } + ], + "source": [ + "x = [b'3 out of 10', b'5 out of 10', b'2 out of 10']\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Extract 3 different integers from 0 to 9 randomly with the same probabilities." + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([5, 4, 0])" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Permutations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Shuffle numbers between 0 and 9 (inclusive)." + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 3 8 4 5 1 0 6 9 7]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[5 2 7 4 1 0 6 8 9 3]\n" + ] + } + ], + "source": [ + "# Or\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Random generator" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Assign number 10 to the seed of the random generator so that you can get the same value next time." + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/10_Random_sampling_Solutions.ipynb b/10_Random_sampling_Solutions.ipynb new file mode 100644 index 0000000..1cc4b87 --- /dev/null +++ b/10_Random_sampling_Solutions.ipynb @@ -0,0 +1,337 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Random Sampling" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "__author__ = 'kyubyong. longinglove@nate.com'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simple random data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Create an array of shape (3, 2) and populate it with random samples from a uniform distribution over [0, 1)." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0.13879034, 0.71300174],\n", + " [ 0.08121322, 0.00393554],\n", + " [ 0.02349471, 0.56677474]])" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.random.rand(3, 2) \n", + "# Or np.random.random((3,2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Create an array of shape (1000, 1000) and populate it with random samples from a standard normal distribution. And verify that the mean and standard deviation is close enough to 0 and 1 repectively." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-0.00110028519551\n", + "0.999683483393\n" + ] + } + ], + "source": [ + "out1 = np.random.randn(1000, 1000)\n", + "out2 = np.random.standard_normal((1000, 1000))\n", + "out3 = np.random.normal(loc=0.0, scale=1.0, size=(1000, 1000))\n", + "assert np.allclose(np.mean(out1), np.mean(out2), atol=0.1)\n", + "assert np.allclose(np.mean(out1), np.mean(out3), atol=0.1)\n", + "assert np.allclose(np.std(out1), np.std(out2), atol=0.1)\n", + "assert np.allclose(np.std(out1), np.std(out3), atol=0.1)\n", + "print np.mean(out3)\n", + "print np.std(out1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Create an array of shape (3, 2) and populate it with random integers ranging from 0 to 3 (inclusive) from a discrete uniform distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 3],\n", + " [3, 0],\n", + " [0, 0]])" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.random.randint(0, 4, (3, 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Extract 1 elements from x randomly such that each of them would be associated with probabilities .3, .5, .2. Then print the result 10 times." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x = [b'3 out of 10', b'5 out of 10', b'2 out of 10']" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 out of 10\n", + "5 out of 10\n", + "3 out of 10\n", + "5 out of 10\n", + "5 out of 10\n", + "5 out of 10\n", + "2 out of 10\n", + "2 out of 10\n", + "5 out of 10\n", + "5 out of 10\n" + ] + } + ], + "source": [ + "for _ in range(10):\n", + " print np.random.choice(x, p=[.3, .5, .2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Extract 3 different integers from 0 to 9 randomly with the same probabilities." + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([5, 4, 0])" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.random.choice(10, 3, replace=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Permutations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Shuffle numbers between 0 and 9 (inclusive)." + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 3 8 4 5 1 0 6 9 7]\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n", + "np.random.shuffle(x)\n", + "print x" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[5 2 7 4 1 0 6 8 9 3]\n" + ] + } + ], + "source": [ + "# Or\n", + "print np.random.permutation(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Random generator" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Assign number 10 to the seed of the random generator so that you can get the same value next time." + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "np.random.seed(10)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/11_Set_routines.ipynb b/11_Set_routines.ipynb new file mode 100644 index 0000000..12ebb12 --- /dev/null +++ b/11_Set_routines.ipynb @@ -0,0 +1,270 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Set routines" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "author = 'kyubyong. longinglove@nate.com'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Making proper sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Get unique elements and reconstruction indices from x. And reconstruct x." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "unique elements = [1 2 3 4 6]\n", + "reconstruction indices = [0 1 4 3 1 2 1]\n", + "reconstructed = [1 2 6 4 2 3 2]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 6, 4, 2, 3, 2])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Boolean operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Create a boolean array of the same shape as x. If each element of x is present in y, the result will be True, otherwise False." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True False False True]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Find the unique intersection of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Find the unique elements of x that are not present in y." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 5]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Find the xor elements of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 4 5]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n", + "out1 = np.setxor1d(x, y)\n", + "out2 = np.sort(np.concatenate((np.setdiff1d(x, y), np.setdiff1d(y, x))))\n", + "assert np.allclose(out1, out2)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Find the union of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2 4 5]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n", + "out1 = np.union1d(x, y)\n", + "out2 = np.sort(np.unique(np.concatenate((x, y))))\n", + "assert np.allclose(out1, out2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/11_Set_routines_Solutions.ipynb b/11_Set_routines_Solutions.ipynb new file mode 100644 index 0000000..6565478 --- /dev/null +++ b/11_Set_routines_Solutions.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Set routines" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "author = 'kyubyong. longinglove@nate.com'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Making proper sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Get unique elements and reconstruction indices from x. And reconstruct x." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "unique elements = [1 2 3 4 6]\n", + "reconstruction indices = [0 1 4 3 1 2 1]\n", + "reconstructed = [1 2 6 4 2 3 2]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 6, 4, 2, 3, 2])\n", + "out, indices = np.unique(x, return_inverse=True)\n", + "print \"unique elements =\", out\n", + "print \"reconstruction indices =\", indices\n", + "print \"reconstructed =\", out[indices]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Boolean operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Create a boolean array of the same shape as x. If each element of x is present in y, the result will be True, otherwise False." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True False False True]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1])\n", + "print np.in1d(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Find the unique intersection of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n", + "print np.intersect1d(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Find the unique elements of x that are not present in y." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 5]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n", + "print np.setdiff1d(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Find the xor elements of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 4 5]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n", + "out1 = np.setxor1d(x, y)\n", + "out2 = np.sort(np.concatenate((np.setdiff1d(x, y), np.setdiff1d(y, x))))\n", + "assert np.allclose(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Find the union of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2 4 5]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 5, 0])\n", + "y = np.array([0, 1, 4])\n", + "out1 = np.union1d(x, y)\n", + "out2 = np.sort(np.unique(np.concatenate((x, y))))\n", + "assert np.allclose(out1, out2)\n", + "print np.union1d(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/12_Sorting_searching_and_counting.ipynb b/12_Sorting_searching_and_counting.ipynb new file mode 100644 index 0000000..bbdda65 --- /dev/null +++ b/12_Sorting_searching_and_counting.ipynb @@ -0,0 +1,444 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Soring, searching, and counting" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = 'kyubyong. longinglove@nate.com'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sorting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Sort x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 4]\n", + " [1 3]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,4],[3,1]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Sort pairs of surnames and first names and return their indices. (first by surname, then by name)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 0]\n" + ] + } + ], + "source": [ + "surnames = ('Hertz', 'Galilei', 'Hertz')\n", + "first_names = ('Heinrich', 'Galileo', 'Gustav')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Get the indices that would sort x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1]\n", + " [1 0]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,4],[3,1]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Create an array such that its fifth element would be the same as the element of sorted x, and it divide other elements by their value." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = [5 1 6 3 9 8 2 7 4 0]\n", + "\n", + "Check the fifth element of this new array is 5, the first four elements are all smaller than 5, and 6th through the end are bigger than 5\n", + "[2 0 4 3 1 5 8 7 6 9]\n" + ] + } + ], + "source": [ + "x = np.random.permutation(10)\n", + "print \"x =\", x\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Create the indices of an array such that its third element would be the same as the element of sorted x, and it divide other elements by their value." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = [2 8 3 7 5 6 4 0 9 1]\n", + "partitioned = [0 1 2 3 4 5 8 6 9 7]\n", + "indices = [0 1 2 3 4 5 8 6 9 7]\n" + ] + } + ], + "source": [ + "x = np.random.permutation(10)\n", + "print \"x =\", x\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Searching" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Get the maximum and minimum values and their indices of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = [[0 5 9 8 2]\n", + " [3 7 4 1 6]]\n", + "maximum values = [9 7]\n", + "max indices = [2 1]\n", + "minimum values = [0 1]\n", + "min indices = [0 3]\n" + ] + } + ], + "source": [ + "x = np.random.permutation(10).reshape(2, 5)\n", + "print \"x =\", x\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Get the maximum and minimum values and their indices of x along the second axis, ignoring NaNs." + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "maximum values ignoring NaNs = [ 4. 3.]\n", + "max indices = [1 0]\n", + "minimum values ignoring NaNs = [ 4. 2.]\n", + "min indices = [1 1]\n" + ] + } + ], + "source": [ + "x = np.array([[np.nan, 4], [3, 2]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Get the values and indices of the elements that are bigger than 2 in x.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Values bigger than 2 = [3 3 5]\n", + "Their indices are (array([0, 1, 1], dtype=int64), array([2, 1, 2], dtype=int64))\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [1, 3, 5]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Get the indices of the elements that are bigger than 2 in the flattend x." + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2 3 4 5]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [1, 3, 5]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Check the elements of x and return 0 if it is less than 0, otherwise the element itself." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 0 0]\n", + " [0 0 0]\n", + " [1 2 3]]\n" + ] + } + ], + "source": [ + "x = np.arange(-5, 4).reshape(3, 3)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Get the indices where elements of y should be inserted to x to maintain order." + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 2, 1, 3], dtype=int64)" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1, 3, 5, 7, 9]\n", + "y = [0, 4, 2, 6]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Counting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Get the number of nonzero elements in x." + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "x = [[0,1,7,0,0],[3,0,0,2,19]]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/12_Sorting_searching_and_counting_Solutions.ipynb b/12_Sorting_searching_and_counting_Solutions.ipynb new file mode 100644 index 0000000..c5a630e --- /dev/null +++ b/12_Sorting_searching_and_counting_Solutions.ipynb @@ -0,0 +1,479 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Soring, searching, and counting" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = 'kyubyong. longinglove@nate.com'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sorting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Sort x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 4]\n", + " [1 3]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,4],[3,1]])\n", + "out = np.sort(x, axis=1)\n", + "x.sort(axis=1)\n", + "assert np.array_equal(out, x)\n", + "print out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Sort pairs of surnames and first names and return their indices. (first by surname, then by name)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 0]\n" + ] + } + ], + "source": [ + "surnames = ('Hertz', 'Galilei', 'Hertz')\n", + "first_names = ('Heinrich', 'Galileo', 'Gustav')\n", + "print np.lexsort((first_names, surnames))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Get the indices that would sort x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1]\n", + " [1 0]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,4],[3,1]])\n", + "out = np.argsort(x, axis=1)\n", + "print out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Create an array such that its fifth element would be the same as the element of sorted x, and it divide other elements by their value." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = [5 1 6 3 9 8 2 7 4 0]\n", + "\n", + "Check the fifth element of this new array is 5, the first four elements are all smaller than 5, and 6th through the end are bigger than 5\n", + "[2 0 4 3 1 5 8 7 6 9]\n" + ] + } + ], + "source": [ + "x = np.random.permutation(10)\n", + "print \"x =\", x\n", + "print \"\\nCheck the fifth element of this new array is 5, the first four elements are all smaller than 5, and 6th through the end are bigger than 5\\n\", \n", + "out = np.partition(x, 5)\n", + "x.partition(5) # in-place equivalent\n", + "assert np.array_equal(x, out)\n", + "print out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Create the indices of an array such that its third element would be the same as the element of sorted x, and it divide other elements by their value." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = [2 8 3 7 5 6 4 0 9 1]\n", + "partitioned = [0 1 2 3 4 5 8 6 9 7]\n", + "indices = [0 1 2 3 4 5 8 6 9 7]\n" + ] + } + ], + "source": [ + "x = np.random.permutation(10)\n", + "print \"x =\", x\n", + "partitioned = np.partition(x, 3)\n", + "indices = np.argpartition(x, 3)\n", + "print \"partitioned =\", partitioned\n", + "print \"indices =\", partitioned\n", + "assert np.array_equiv(x[indices], partitioned)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Searching" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Get the maximum and minimum values and their indices of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x = [[0 5 9 8 2]\n", + " [3 7 4 1 6]]\n", + "maximum values = [9 7]\n", + "max indices = [2 1]\n", + "minimum values = [0 1]\n", + "min indices = [0 3]\n" + ] + } + ], + "source": [ + "x = np.random.permutation(10).reshape(2, 5)\n", + "print \"x =\", x\n", + "print \"maximum values =\", np.max(x, 1)\n", + "print \"max indices =\", np.argmax(x, 1)\n", + "print \"minimum values =\", np.min(x, 1)\n", + "print \"min indices =\", np.argmin(x, 1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Get the maximum and minimum values and their indices of x along the second axis, ignoring NaNs." + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "maximum values ignoring NaNs = [ 4. 3.]\n", + "max indices = [1 0]\n", + "minimum values ignoring NaNs = [ 4. 2.]\n", + "min indices = [1 1]\n" + ] + } + ], + "source": [ + "x = np.array([[np.nan, 4], [3, 2]])\n", + "print \"maximum values ignoring NaNs =\", np.nanmax(x, 1)\n", + "print \"max indices =\", np.nanargmax(x, 1)\n", + "print \"minimum values ignoring NaNs =\", np.nanmin(x, 1)\n", + "print \"min indices =\", np.nanargmin(x, 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Get the values and indices of the elements that are bigger than 2 in x.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Values bigger than 2 = [3 3 5]\n", + "Their indices are (array([0, 1, 1], dtype=int64), array([2, 1, 2], dtype=int64))\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [1, 3, 5]])\n", + "print \"Values bigger than 2 =\", x[x>2]\n", + "print \"Their indices are \", np.nonzero(x > 2)\n", + "assert np.array_equiv(x[x>2], x[np.nonzero(x > 2)])\n", + "assert np.array_equiv(x[x>2], np.extract(x > 2, x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Get the indices of the elements that are bigger than 2 in the flattend x." + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2 3 4 5]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [1, 3, 5]])\n", + "print np.flatnonzero(x)\n", + "assert np.array_equiv(np.flatnonzero(x), x.ravel().nonzero())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Check the elements of x and return 0 if it is less than 0, otherwise the element itself." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 0 0]\n", + " [0 0 0]\n", + " [1 2 3]]\n" + ] + } + ], + "source": [ + "x = np.arange(-5, 4).reshape(3, 3)\n", + "print np.where(x <0, 0, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Get the indices where elements of y should be inserted to x to maintain order." + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 2, 1, 3], dtype=int64)" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1, 3, 5, 7, 9]\n", + "y = [0, 4, 2, 6]\n", + "np.searchsorted(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Counting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Get the number of nonzero elements in x." + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "x = [[0,1,7,0,0],[3,0,0,2,19]]\n", + "print np.count_nonzero(x)\n", + "assert np.count_nonzero(x) == len(x[x!=0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/13_Statistics.ipynb b/13_Statistics.ipynb new file mode 100644 index 0000000..b5cb14a --- /dev/null +++ b/13_Statistics.ipynb @@ -0,0 +1,579 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Statistics" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "__author__ = \"kyubyong. kbpark.linguist@gmail.com\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.3'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Order statistics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Return the minimum value of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[0 1]\n", + " [2 3]]\n", + "ans=\n", + " [0 2]\n" + ] + } + ], + "source": [ + "x = np.arange(4).reshape((2, 2))\n", + "print(\"x=\\n\", x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Return the maximum value of x along the second axis. Reduce the second axis to the dimension with size one." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[0 1]\n", + " [2 3]]\n", + "ans=\n", + " [[1]\n", + " [3]]\n" + ] + } + ], + "source": [ + "x = np.arange(4).reshape((2, 2))\n", + "print(\"x=\\n\", x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Calcuate the difference between the maximum and the minimum of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[0 1 2 3 4]\n", + " [5 6 7 8 9]]\n", + "ans=\n", + " [4 4]\n" + ] + } + ], + "source": [ + "x = np.arange(10).reshape((2, 5))\n", + "print(\"x=\\n\", x)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Compute the 75th percentile of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[ 1 2 3 4 5]\n", + " [ 6 7 8 9 10]]\n", + "ans=\n", + " [ 4. 9.]\n" + ] + } + ], + "source": [ + "x = np.arange(1, 11).reshape((2, 5))\n", + "print(\"x=\\n\", x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Averages and variances" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Compute the median of flattened x." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[1 2 3]\n", + " [4 5 6]\n", + " [7 8 9]]\n", + "ans=\n", + " 5.0\n" + ] + } + ], + "source": [ + "x = np.arange(1, 10).reshape((3, 3))\n", + "print(\"x=\\n\", x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Compute the weighted average of x." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.66666666667\n" + ] + } + ], + "source": [ + "x = np.arange(5)\n", + "weights = np.arange(1, 6)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Compute the mean, standard deviation, and variance of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [0 1 2 3 4]\n", + "mean=\n", + " 2.0\n", + "std=\n", + " 1.41421356237\n", + "variance=\n", + " 2.0\n" + ] + } + ], + "source": [ + "x = np.arange(5)\n", + "print(\"x=\\n\",x)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Correlating" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Compute the covariance matrix of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [[ 1. -1.]\n", + " [-1. 1.]]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2])\n", + "y = np.array([2, 1, 0])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. In the above covariance matrix, what does the -1 mean?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Compute Pearson product-moment correlation coefficients of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [[ 1. 0.92857143]\n", + " [ 0.92857143 1. ]]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 3])\n", + "y = np.array([2, 4, 5])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Compute cross-correlation of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [19]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 3])\n", + "y = np.array([2, 4, 5])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Histograms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Compute the histogram of x against the bins." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " (array([2, 3, 1], dtype=int64), array([0, 1, 2, 3]))\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x = np.array([0.5, 0.7, 1.0, 1.2, 1.3, 2.1])\n", + "bins = np.array([0, 1, 2, 3])\n", + "print(\"ans=\\n\", ...)\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "plt.hist(x, bins=bins)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Compute the 2d histogram of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [[ 3. 0. 0. 0.]\n", + " [ 0. 2. 0. 0.]\n", + " [ 0. 0. 1. 1.]]\n" + ] + }, + { + "data": { + "image/png": "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\nccIrqwsyszzmVpyZ5TG3Ypp6QScAEXEvMApcV7SxGPgasGK2FUZHR+l0OpMea9asYd++fZPWO3jw\nIJ1OZ9r2W7ZsYc+ePZOWjY2N0el0OHny5KTlO3bsYOfOnZOWnThxgk6nM+0rud27d08bdz0+Pk6n\n05l2975ut8umTZum1bZhw4ZK9mPPnj2LYj8W8vNYvnz5otgPWNjPA1gU+7GQn8fy5csXxX7Awn4e\ny5cvXxT7AeV/Ht1u97m/jSMjI3Q6HbZu3TptmzJU/s3FoLF4A3BtSuk7me9xEPhJSunNZ3nNby4k\nScpQ1TcXlY4WiYiPATcBHeCfIuKCwUs/Tik9O1jnA8C/OXPKIyLuAL4L/D1wLvAO4HXA66usVZIk\nlaPq0yLvAl4MPAx8f8Lj9yes83LgwgnPXwh8CPjmYLvfBK5PKT1cca2tc7avrjU7M8tjbsWZWR5z\nq4eq57mYs3lJKW2a8vwe4J7KitJzxsfHh11C45hZHnMrzszymFs9LNhokap4zYUkSXkaPVpEkiS1\nh82FJEkqlc1Fi00df625mVkecyvOzPKYWz3YXLTY5s2bh11C45hZHnMrzszymFs92Fy02J133jns\nEhrHzPKYW3Fmlsfc6sHmosUcXVOcmeUxt+LMLI+51YPNhSRJKpXNhSRJKpXNRYtNvYuf5mZmecyt\nODPLY271YHPRYmNjpU3G1hpmlsfcijOzPOZWD07/LUlSSzn9tyRJagSbC0mSVCqbC0mSVCqbixbr\ndDrDLqFxzCyPuRVnZnnMrR5sLlrstttuG3YJjWNmecytODPLY2714GgRSZJaytEikiSpEWwuJElS\nqWwuWmzfvn3DLqFxzCyPuRVnZnnMrR5sLlqs2+0Ou4TGMbM85lacmeUxt3rwgk5JklrKCzolSVIj\n2FxIkqRS2VxIkqRS2Vy02KZNm4ZdQuOYWR5zK87M8phbPdhctNi6deuGXULjmFkecyvOzPKYWz1U\nOlokIv4IeCNwCfBT4CvA+1JKvTm2uw74EPDrwAngf00pfXqGdR0tIklShqaOFnktsBu4ElgLvAA4\nGBG/PNMGEXER8HngC8ArgY8Cn4yI11dcqyRJKsE5Vb55Sml04vOIeDvwNHAFcHiGzd4NfCeltH3w\n/NsR8bvAVuBvKipVktRwvV6P48ePs2LFClauXDnsclptoa+5eCmQgFOzrHMVcGjKsgPAmqqKaqvD\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "xedges = [0, 1, 2, 3]\n", + "yedges = [0, 1, 2, 3, 4]\n", + "x = np.array([0, 0.1, 0.2, 1., 1.1, 2., 2.1])\n", + "y = np.array([0, 0.1, 0.2, 1., 1.1, 2., 3.3])\n", + "...\n", + "\n", + "plt.scatter(x, y)\n", + "plt.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Count number of occurrences of 0 through 7 in x." + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [1 3 1 1 0 0 0 1]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 1, 3, 2, 1, 7])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Return the indices of the bins to which each value in x belongs." + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [1 4 3 2]\n" + ] + } + ], + "source": [ + "x = np.array([0.2, 6.4, 3.0, 1.6])\n", + "bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [conda root]", + "language": "python", + "name": "conda-root-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/13_Statistics_solutions.ipynb b/13_Statistics_solutions.ipynb new file mode 100644 index 0000000..5ffc7c6 --- /dev/null +++ b/13_Statistics_solutions.ipynb @@ -0,0 +1,618 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Statistics" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "__author__ = \"kyubyong. kbpark.linguist@gmail.com\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.3'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Order statistics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Return the minimum value of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[0 1]\n", + " [2 3]]\n", + "ans=\n", + " [0 2]\n" + ] + } + ], + "source": [ + "x = np.arange(4).reshape((2, 2))\n", + "print(\"x=\\n\", x)\n", + "print(\"ans=\\n\", np.amin(x, 1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Return the maximum value of x along the second axis. Reduce the second axis to the dimension with size one." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[0 1]\n", + " [2 3]]\n", + "ans=\n", + " [[1]\n", + " [3]]\n" + ] + } + ], + "source": [ + "x = np.arange(4).reshape((2, 2))\n", + "print(\"x=\\n\", x)\n", + "print(\"ans=\\n\", np.amax(x, 1, keepdims=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Calcuate the difference between the maximum and the minimum of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[0 1 2 3 4]\n", + " [5 6 7 8 9]]\n", + "ans=\n", + " [4 4]\n" + ] + } + ], + "source": [ + "x = np.arange(10).reshape((2, 5))\n", + "print(\"x=\\n\", x)\n", + "\n", + "out1 = np.ptp(x, 1)\n", + "out2 = np.amax(x, 1) - np.amin(x, 1)\n", + "assert np.allclose(out1, out2)\n", + "print(\"ans=\\n\", out1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Compute the 75th percentile of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[ 1 2 3 4 5]\n", + " [ 6 7 8 9 10]]\n", + "ans=\n", + " [ 4. 9.]\n" + ] + } + ], + "source": [ + "x = np.arange(1, 11).reshape((2, 5))\n", + "print(\"x=\\n\", x)\n", + "\n", + "print(\"ans=\\n\", np.percentile(x, 75, 1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Averages and variances" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Compute the median of flattened x." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [[1 2 3]\n", + " [4 5 6]\n", + " [7 8 9]]\n", + "ans=\n", + " 5.0\n" + ] + } + ], + "source": [ + "x = np.arange(1, 10).reshape((3, 3))\n", + "print(\"x=\\n\", x)\n", + "\n", + "print(\"ans=\\n\", np.median(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Compute the weighted average of x." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.66666666667\n" + ] + } + ], + "source": [ + "x = np.arange(5)\n", + "weights = np.arange(1, 6)\n", + "\n", + "out1 = np.average(x, weights=weights)\n", + "out2 = (x*(weights/weights.sum())).sum()\n", + "assert np.allclose(out1, out2)\n", + "print(out1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Compute the mean, standard deviation, and variance of x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x=\n", + " [0 1 2 3 4]\n", + "mean=\n", + " 2.0\n", + "std=\n", + " 1.41421356237\n", + "variance=\n", + " 2.0\n" + ] + } + ], + "source": [ + "x = np.arange(5)\n", + "print(\"x=\\n\",x)\n", + "\n", + "out1 = np.mean(x)\n", + "out2 = np.average(x)\n", + "assert np.allclose(out1, out2)\n", + "print(\"mean=\\n\", out1)\n", + "\n", + "out3 = np.std(x)\n", + "out4 = np.sqrt(np.mean((x - np.mean(x)) ** 2 ))\n", + "assert np.allclose(out3, out4)\n", + "print(\"std=\\n\", out3)\n", + "\n", + "out5 = np.var(x)\n", + "out6 = np.mean((x - np.mean(x)) ** 2 )\n", + "assert np.allclose(out5, out6)\n", + "print(\"variance=\\n\", out5)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Correlating" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Compute the covariance matrix of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [[ 1. -1.]\n", + " [-1. 1.]]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2])\n", + "y = np.array([2, 1, 0])\n", + "\n", + "print(\"ans=\\n\", np.cov(x, y))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. In the above covariance matrix, what does the -1 mean?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It means `x` and `y` correlate perfectly in opposite directions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Compute Pearson product-moment correlation coefficients of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [[ 1. 0.92857143]\n", + " [ 0.92857143 1. ]]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 3])\n", + "y = np.array([2, 4, 5])\n", + "\n", + "print(\"ans=\\n\", np.corrcoef(x, y))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Compute cross-correlation of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [19]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 3])\n", + "y = np.array([2, 4, 5])\n", + "\n", + "print(\"ans=\\n\", np.correlate(x, y))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Histograms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Compute the histogram of x against the bins." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " (array([2, 3, 1], dtype=int64), array([0, 1, 2, 3]))\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "x = np.array([0.5, 0.7, 1.0, 1.2, 1.3, 2.1])\n", + "bins = np.array([0, 1, 2, 3])\n", + "print(\"ans=\\n\", np.histogram(x, bins))\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "plt.hist(x, bins=bins)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Compute the 2d histogram of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [[ 3. 0. 0. 0.]\n", + " [ 0. 2. 0. 0.]\n", + " [ 0. 0. 1. 1.]]\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhcAAAFkCAYAAACThxm6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzt3X2wHXd95/n3NzLgyLWAZhx8yawVL9aDPXnA2CG2cLDN\nWEie66rDEKhobCNA8lI8yI5XVCQqVVsrm6rFSB4gRDYhBVpCRuHYqd1ZQWFHUgQxlAo8bHwxbCWI\nIwk88gK2EXJBNhezifjtH+fI3Afdh/65+57u2+9X1Snu6dN97rc/p+X75XT/fh0pJSRJksryS8Mu\nQJIkLS42F5IkqVQ2F5IkqVQ2F5IkqVQ2F5IkqVQ2F5IkqVQ2F5IkqVQ2F5IkqVQ2F5IkqVQ2F5Ik\nqVSVNhcR8a6I+EZE/Hjw+EpE3DDL+tdGxM+nPE5HxMuqrFOSJJXnnIrf/wngfcBRIIC3A5+NiMtS\nSt+aYZsErAL+8bkFKT1dcZ2SJKkksdA3LouIHwF/mFL61Fleuxb4IrAspfSTBS1MkiSVYsGuuYiI\nX4qI/wgsBb4626rAYxHx/Yg4GBGvWZgKJUlSGao+LUJE/Ab9ZuJc+qc63phSOjLD6j8A3gn8HfAi\n4B3AwxHxOymlx2Z4/38NrAceB54tt3pJkha1c4GLgAMppR+V9aaVnxaJiHOA5cBLgDfTbxiumaXB\nmLr9w8B/Sym9bYbXbwb+spxqJUlqpVtSSp8p680q/+YipfQvwHcGT78eEb8D3AG8e55v8TXg6lle\nfxxg7969XHrppbllttLWrVv5yEc+MuwyGsXM8phbcWaWx9yK+da3vsVb3vIWGPwtLUvlzcVZ/BL9\nUx7zdRn90yUzeRbg0ksv5fLLL38+dbXOS17yEjMryMzymFtxZpbH3LKVellBpc1FRHwA+GvgBPDf\nAbcA1wLrBq/fDfzqmVMeEXEH8F3g7+mfB3oH8Drg9VXW2VZPPvnksEtoHDPLY27FmVkec6uHqr+5\neBnwaeDlwI+BbwLrUkpfHLw+Alw4Yf0XAh8CfhUYH6x/fUrpyxXX2Urf+973hl1C45hZHnMrzszy\nmFs9VNpcpJT+xzle3zTl+T3APVXWpF+44oorhl1C45hZHnMrzszymFs9eG+RFrvpppuGXULjmFke\ncyvOzPKYWz0s+AydZYuIy4FHH330US/ikSSpgLGxsTPf9lyRUhor63395kKSJJXK5qLFNm3aNPdK\nmsTM8phbcWaWx9zqweaixdatWzfsEhrHzPKYW3Fmlsfc6sFrLiRJaqmqrrkYxgydkiTVSq/X4/jx\n46xYsYKVK1cOu5zG87SIJKm1Tp06xQ033Mjq1asZHR1l1apV3HDDjTzzzDPDLq3RbC5a7PDhw8Mu\noXHMLI+5FWdmeYrmdvPNGzl06BFgL/07Vezl0KFHuOmmt1RRXmvYXLTYrl27hl1C45hZHnMrzszy\nFMmt1+tx4MBDnD79J/RvfXUhcAunT3+UAwce4ujRo1WVuejZXLTY/fffP+wSGsfM8phbcWaWp0hu\nx48fH/x0zZRXrgXg2LFj5RTVQjYXLbZ06dJhl9A4ZpbH3IozszxFcrv44osHP029N+aXAFixYkU5\nRbWQzYUkqZVWrVrF+vWjLFnyB/SvuXgC2MuSJXewfv2oo0aeB5sLSVJrdbt7Wbv2KmAjsBzYyNq1\nV9Ht7h1yZc1mc9Fi27ZtG3YJjWNmecytODPLUzS3ZcuWsX//g/R6PR566CF6vR779z/IsmXLKqqw\nHZxEq8WWL18+7BIax8zymFtxZpYnN7eVK1d6GqRETv8tSVJLect1SZLUCDYXkiSpVDYXLXbkyJFh\nl9A4ZpbH3IozszzmVg82Fy22ffv2YZfQOGaWx9yKM7M85lYPNhctdu+99w67hMYxszzmVpyZ5TG3\nerC5aDGHuhVnZnnMrTgzy2Nu9WBzIUmSSmVzIUmSSmVz0WI7d+4cdgmNY2Z5zK04M8tjbvVgc9Fi\n4+Pjwy6hccwsj7kVZ2Z5zK0enP5bkqSWauT03xHxroj4RkT8ePD4SkTcMMc210XEoxHxbET0IuJt\nVdYoSZLKVfVpkSeA9wGXA1cAXwQ+GxGXnm3liLgI+DzwBeCVwEeBT0bE6yuuU5IklaTS5iKl9GBK\naX9K6XhK6VhK6X8G/l/gqhk2eTfwnZTS9pTSt1NK9wH/O7C1yjrb6uTJk8MuoXHMLI+5FWdmecyt\nHhbsgs6I+KWI+I/AUuCrM6x2FXBoyrIDwJoqa2urzZs3D7uExjGzPOZWnJnlMbd6OKfqXxARv0G/\nmTgX+EfgjSmlme4sMwI8NWXZU8CLI+JFKaWfVVdp+9x5553DLqFxzCyPuRVnZnnMrR4W4puLI/Sv\nn/gd4E+Bv4iIS8r+JaOjo3Q6nUmPNWvWsG/fvknrHTx4kE6nM237LVu2sGfPnknLxsbG6HQ6075m\n27Fjx7Sx1CdOnKDT6Uy7I9/u3bvZtm3bpGXj4+N0Oh0OHz48aXm322XTpk3TatuwYUMl+/HZz352\nUezHQn4el19++aLYD1jYz+P8889fFPuxkJ/H5Zdfvij2Axb287j88ssXxX5A+Z9Ht9t97m/jyMgI\nnU6HrVuruepgwYeiRsTfAMdSSu8+y2tfAh5NKb13wrK3Ax9JKS2b4f0ciipJUoZGDkWd5Xe+aIbX\nvgpcP2XZOma+RkOSJNVM1fNcfCAiXhsRvxYRvxERdwPXAnsHr98dEZ+esMnHgVdExM6IWB0R7wHe\nDHy4yjrbaurXeJqbmeUxt+LMLI+51UPV31y8DPg0/esuDtGf62JdSumLg9dHgAvPrJxSehy4EVgL\nPEZ/COqtKaWpI0hUgrGx0r4Baw0zy2NuxZlZHnOrB6f/liSppRbTNReSJGkRs7mQJEmlsrmQJEml\nsrlosbNNBqPZmVkecyvOzPKYWz3YXLTYbbfdNuwSGsfM8phbcWaWx9zqwdEikiS1lKNFJElSI9hc\nSJKkUtlctNjUO/5pbmaWx9yKM7M85lYPNhct1u12h11C45hZHnMrzszymFs9eEGnJEkt5QWdkiSp\nEWwuJElSqWwuJElSqWwuWmzTpk3DLqFxzCyPuRVnZnnMrR5sLlps3bp1wy6hccwsj7kVZ2Z5zK0e\nHC0iSVJLOVpEkiQ1gs2FJEkqlc1Fix0+fHjYJTSOmeUxt+LMLI+51YPNRYvt2rVr2CU0jpnlMbfi\nzCyPudWDF3S22Pj4OEuXLh12GY1iZnnMrTgzy2NuxXhBp0rnP8DizCyPuRVnZnnMrR5sLiRJUqls\nLiRJUqlsLlps27Ztwy6hccwsj7kVZ2Z5zK0ebC5abPny5cMuoXHMLI+5FWdmecytHiodLRIRfwS8\nEbgE+CnwFeB9KaXeLNtcC/ztlMUJeHlK6emzrO9oEUmSMjR1tMhrgd3AlcBa4AXAwYj45Tm2S8BK\nYGTwOGtjIUmS6uecKt88pTQ68XlEvB14GrgCmGsatR+mlH5SUWmSJKkiC33NxUvpfytxao71Angs\nIr4fEQcj4jXVl9Y+R44cGXYJjWNmecytODPLY271sGDNRUQE8MfA4ZTSP8yy6g+AdwJvAn4PeAJ4\nOCIuq77Kdtm+ffuwS2gcM8tjbsWZWR5zq4cFm/47Iv4UWA9cnVL6QcFtHwb+W0rpbWd5zQs6M504\nccIrqwsyszzmVpyZ5TG3Ypp6QScAEXEvMApcV7SxGPgasGK2FUZHR+l0OpMea9asYd++fZPWO3jw\nIJ1OZ9r2W7ZsYc+ePZOWjY2N0el0OHny5KTlO3bsYOfOnZOWnThxgk6nM+0rud27d08bdz0+Pk6n\n05l2975ut8umTZum1bZhw4ZK9mPPnj2LYj8W8vNYvnz5otgPWNjPA1gU+7GQn8fy5csXxX7Awn4e\ny5cvXxT7AeV/Ht1u97m/jSMjI3Q6HbZu3TptmzJU/s3FoLF4A3BtSuk7me9xEPhJSunNZ3nNby4k\nScpQ1TcXlY4WiYiPATcBHeCfIuKCwUs/Tik9O1jnA8C/OXPKIyLuAL4L/D1wLvAO4HXA66usVZIk\nlaPq0yLvAl4MPAx8f8Lj9yes83LgwgnPXwh8CPjmYLvfBK5PKT1cca2tc7avrjU7M8tjbsWZWR5z\nq4eq57mYs3lJKW2a8vwe4J7KitJzxsfHh11C45hZHnMrzszymFs9LNhokap4zYUkSXkaPVpEkiS1\nh82FJEkqlc1Fi00df625mVkecyvOzPKYWz3YXLTY5s2bh11C45hZHnMrzszymFs92Fy02J133jns\nEhrHzPKYW3Fmlsfc6sHmosUcXVOcmeUxt+LMLI+51YPNhSRJKpXNhSRJKpXNRYtNvYuf5mZmecyt\nODPLY271YHPRYmNjpU3G1hpmlsfcijOzPOZWD07/LUlSSzn9tyRJagSbC0mSVCqbC0mSVCqbixbr\ndDrDLqFxzCyPuRVnZnnMrR5sLlrstttuG3YJjWNmecytODPLY2714GgRSZJaytEikiSpEWwuJElS\nqWwuWmzfvn3DLqFxzCyPuRVnZnnMrR5sLlqs2+0Ou4TGMbM85lacmeUxt3rwgk5JklrKCzolSVIj\n2FxIkqRS2VxIkqRS2Vy02KZNm4ZdQuOYWR5zK87M8phbPdhctNi6deuGXULjmFkecyvOzPKYWz1U\nOlokIv4IeCNwCfBT4CvA+1JKvTm2uw74EPDrwAngf00pfXqGdR0tIklShqaOFnktsBu4ElgLvAA4\nGBG/PNMGEXER8HngC8ArgY8Cn4yI11dcqyRJKsE5Vb55Sml04vOIeDvwNHAFcHiGzd4NfCeltH3w\n/NsR8bvAVuBvKipVktRwvV6P48ePs2LFClauXDnsclptoa+5eCmQgFOzrHMVcGjKsgPAmqqKaqvD\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "xedges = [0, 1, 2, 3]\n", + "yedges = [0, 1, 2, 3, 4]\n", + "x = np.array([0, 0.1, 0.2, 1., 1.1, 2., 2.1])\n", + "y = np.array([0, 0.1, 0.2, 1., 1.1, 2., 3.3])\n", + "H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges))\n", + "print(\"ans=\\n\", H)\n", + "\n", + "plt.scatter(x, y)\n", + "plt.grid()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Count number of occurrences of 0 through 7 in x." + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [1 3 1 1 0 0 0 1]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 1, 3, 2, 1, 7])\n", + "print(\"ans=\\n\", np.bincount(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Return the indices of the bins to which each value in x belongs." + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ans=\n", + " [1 4 3 2]\n" + ] + } + ], + "source": [ + "x = np.array([0.2, 6.4, 3.0, 1.6])\n", + "bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])\n", + "\n", + "print(\"ans=\\n\", np.digitize(x, bins))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [conda root]", + "language": "python", + "name": "conda-root-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/1_Array_creation_routines.ipynb b/1_Array_creation_routines.ipynb new file mode 100644 index 0000000..71790b6 --- /dev/null +++ b/1_Array_creation_routines.ipynb @@ -0,0 +1,798 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Array creation routines" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ones and zeros" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 2*2 integers, without initializing entries." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 0]])" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let X = np.array([1,2,3], [4,5,6], np.int32). \n", + "Create a new array with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 2, 3],\n", + " [4, 5, 6]])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = np.array([[1,2,3], [4,5,6]], np.int32)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 3-D array with ones on the diagonal and zeros elsewhere." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 0., 0.],\n", + " [ 0., 1., 0.],\n", + " [ 0., 0., 1.]])" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 0., 0.],\n", + " [ 0., 1., 0.],\n", + " [ 0., 0., 1.]])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 3*2 float numbers, filled with ones." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 1.],\n", + " [ 1., 1.],\n", + " [ 1., 1.]])" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.arange(4, dtype=np.int64). Create an array of ones with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 1, 1, 1], dtype=int64)" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(4, dtype=np.int64)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 3*2 float numbers, filled with zeros." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 0.],\n", + " [ 0., 0.],\n", + " [ 0., 0.]])" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.arange(4, dtype=np.int64). Create an array of zeros with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 0, 0, 0], dtype=int64)" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(4, dtype=np.int64)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 2*5 uints, filled with 6." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[6, 6, 6, 6, 6],\n", + " [6, 6, 6, 6, 6]], dtype=uint32)" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.arange(4, dtype=np.int64). Create an array of 6's with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([6, 6, 6, 6], dtype=int64)" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(4, dtype=np.int64)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## From existing data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array of [1, 2, 3]." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2, 3])" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = [1, 2]. Convert it into an array." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2])" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1,2]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let X = np.array([[1, 2], [3, 4]]). Convert it into a matrix." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "matrix([[1, 2],\n", + " [3, 4]])" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = np.array([[1, 2], [3, 4]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = [1, 2]. Conver it into an array of `float`." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1., 2.])" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1, 2]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.array([30]). Convert it into scalar of its single element, i.e. 30." + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.array([30])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.array([1, 2, 3]). Create a array copy of x, which has a different id from x." + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "70140352 [1 2 3]\n", + "70140752 [1 2 3]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Numerical ranges" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array of 2, 4, 6, 8, ..., 100." + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26,\n", + " 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52,\n", + " 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78,\n", + " 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100])" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 1-D array of 50 evenly spaced elements between 3. and 10., inclusive." + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 3. , 3.14285714, 3.28571429, 3.42857143,\n", + " 3.57142857, 3.71428571, 3.85714286, 4. ,\n", + " 4.14285714, 4.28571429, 4.42857143, 4.57142857,\n", + " 4.71428571, 4.85714286, 5. , 5.14285714,\n", + " 5.28571429, 5.42857143, 5.57142857, 5.71428571,\n", + " 5.85714286, 6. , 6.14285714, 6.28571429,\n", + " 6.42857143, 6.57142857, 6.71428571, 6.85714286,\n", + " 7. , 7.14285714, 7.28571429, 7.42857143,\n", + " 7.57142857, 7.71428571, 7.85714286, 8. ,\n", + " 8.14285714, 8.28571429, 8.42857143, 8.57142857,\n", + " 8.71428571, 8.85714286, 9. , 9.14285714,\n", + " 9.28571429, 9.42857143, 9.57142857, 9.71428571,\n", + " 9.85714286, 10. ])" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 1-D array of 50 element spaced evenly on a log scale between 3. and 10., exclusive." + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1.00000000e+03, 1.38038426e+03, 1.90546072e+03,\n", + " 2.63026799e+03, 3.63078055e+03, 5.01187234e+03,\n", + " 6.91830971e+03, 9.54992586e+03, 1.31825674e+04,\n", + " 1.81970086e+04, 2.51188643e+04, 3.46736850e+04,\n", + " 4.78630092e+04, 6.60693448e+04, 9.12010839e+04,\n", + " 1.25892541e+05, 1.73780083e+05, 2.39883292e+05,\n", + " 3.31131121e+05, 4.57088190e+05, 6.30957344e+05,\n", + " 8.70963590e+05, 1.20226443e+06, 1.65958691e+06,\n", + " 2.29086765e+06, 3.16227766e+06, 4.36515832e+06,\n", + " 6.02559586e+06, 8.31763771e+06, 1.14815362e+07,\n", + " 1.58489319e+07, 2.18776162e+07, 3.01995172e+07,\n", + " 4.16869383e+07, 5.75439937e+07, 7.94328235e+07,\n", + " 1.09647820e+08, 1.51356125e+08, 2.08929613e+08,\n", + " 2.88403150e+08, 3.98107171e+08, 5.49540874e+08,\n", + " 7.58577575e+08, 1.04712855e+09, 1.44543977e+09,\n", + " 1.99526231e+09, 2.75422870e+09, 3.80189396e+09,\n", + " 5.24807460e+09, 7.24435960e+09])" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building matrices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let X = np.array([[ 0, 1, 2, 3],\n", + " [ 4, 5, 6, 7],\n", + " [ 8, 9, 10, 11]]).\n", + " Get the diagonal of X, that is, [0, 5, 10]." + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 5, 10])" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = np.array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 2-D array whose diagonal equals [1, 2, 3, 4] and 0's elsewhere." + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 0, 0, 0],\n", + " [0, 2, 0, 0],\n", + " [0, 0, 3, 0],\n", + " [0, 0, 0, 4]])" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array which looks like below.\n", + "array([[ 0., 0., 0., 0., 0.],\n", + " [ 1., 0., 0., 0., 0.],\n", + " [ 1., 1., 0., 0., 0.]])" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 0., 0., 0., 0.],\n", + " [ 1., 0., 0., 0., 0.],\n", + " [ 1., 1., 0., 0., 0.]])" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array which looks like below.\n", + "array([[ 0, 0, 0],\n", + " [ 4, 0, 0],\n", + " [ 7, 8, 0],\n", + " [10, 11, 12]])" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 0, 0],\n", + " [ 4, 0, 0],\n", + " [ 7, 8, 0],\n", + " [10, 11, 12]])" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array which looks like below. array([[ 1, 2, 3],\n", + " [ 4, 5, 6],\n", + " [ 0, 8, 9],\n", + " [ 0, 0, 12]])" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1, 2, 3],\n", + " [ 4, 5, 6],\n", + " [ 0, 8, 9],\n", + " [ 0, 0, 12]])" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/1_Array_creation_routines_Solution.ipynb b/1_Array_creation_routines_Solution.ipynb new file mode 100644 index 0000000..fb1ecfd --- /dev/null +++ b/1_Array_creation_routines_Solution.ipynb @@ -0,0 +1,949 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Array creation routines" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ones and zeros" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 2*2 integers, without initializing entries." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0, 0],\n", + " [0, 0]])" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.empty([2,2], int)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let X = np.array([1,2,3], [4,5,6], np.int32). \n", + "Create a new array with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 2, 3],\n", + " [4, 5, 6]])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = np.array([[1,2,3], [4,5,6]], np.int32)\n", + "np.empty_like(X)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 3-D array with ones on the diagonal and zeros elsewhere." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 0., 0.],\n", + " [ 0., 1., 0.],\n", + " [ 0., 0., 1.]])" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.eye(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 0., 0.],\n", + " [ 0., 1., 0.],\n", + " [ 0., 0., 1.]])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.identity(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 3*2 float numbers, filled with ones." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 1.],\n", + " [ 1., 1.],\n", + " [ 1., 1.]])" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.ones([3,2], float)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.arange(4, dtype=np.int64). Create an array of ones with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 1, 1, 1], dtype=int64)" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(4, dtype=np.int64)\n", + "np.ones_like(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 3*2 float numbers, filled with zeros." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 0.],\n", + " [ 0., 0.],\n", + " [ 0., 0.]])" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.zeros((3,2), float)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.arange(4, dtype=np.int64). Create an array of zeros with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 0, 0, 0], dtype=int64)" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(4, dtype=np.int64)\n", + "np.zeros_like(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a new array of 2*5 uints, filled with 6." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[6, 6, 6, 6, 6],\n", + " [6, 6, 6, 6, 6]], dtype=uint32)" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.full((2, 5), 6, dtype=np.uint)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[6, 6, 6, 6, 6],\n", + " [6, 6, 6, 6, 6]], dtype=uint32)" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.ones([2, 5], dtype=np.uint) * 6" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.arange(4, dtype=np.int64). Create an array of 6's with the same shape and type as X." + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([6, 6, 6, 6], dtype=int64)" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(4, dtype=np.int64)\n", + "np.full_like(x, 6)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([6, 6, 6, 6], dtype=int64)" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.ones_like(x) * 6" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## From existing data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array of [1, 2, 3]." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2, 3])" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.array([1, 2, 3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = [1, 2]. Convert it into an array." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2])" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1,2]\n", + "np.asarray(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let X = np.array([[1, 2], [3, 4]]). Convert it into a matrix." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "matrix([[1, 2],\n", + " [3, 4]])" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = np.array([[1, 2], [3, 4]])\n", + "np.asmatrix(X)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = [1, 2]. Conver it into an array of `float`." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1., 2.])" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = [1, 2]\n", + "np.asfarray(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1., 2.])" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.asarray(x, float)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.array([30]). Convert it into scalar of its single element, i.e. 30." + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.array([30])\n", + "np.asscalar(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "30" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let x = np.array([1, 2, 3]). Create a array copy of x, which has a different id from x." + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "70140352 [1 2 3]\n", + "70140752 [1 2 3]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3])\n", + "y = np.copy(x)\n", + "print id(x), x\n", + "print id(y), y" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Numerical ranges" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array of 2, 4, 6, 8, ..., 100." + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26,\n", + " 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52,\n", + " 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78,\n", + " 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100])" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.arange(2, 101, 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 1-D array of 50 evenly spaced elements between 3. and 10., inclusive." + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 3. , 3.14285714, 3.28571429, 3.42857143,\n", + " 3.57142857, 3.71428571, 3.85714286, 4. ,\n", + " 4.14285714, 4.28571429, 4.42857143, 4.57142857,\n", + " 4.71428571, 4.85714286, 5. , 5.14285714,\n", + " 5.28571429, 5.42857143, 5.57142857, 5.71428571,\n", + " 5.85714286, 6. , 6.14285714, 6.28571429,\n", + " 6.42857143, 6.57142857, 6.71428571, 6.85714286,\n", + " 7. , 7.14285714, 7.28571429, 7.42857143,\n", + " 7.57142857, 7.71428571, 7.85714286, 8. ,\n", + " 8.14285714, 8.28571429, 8.42857143, 8.57142857,\n", + " 8.71428571, 8.85714286, 9. , 9.14285714,\n", + " 9.28571429, 9.42857143, 9.57142857, 9.71428571,\n", + " 9.85714286, 10. ])" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linspace(3., 10, 50)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 1-D array of 50 element spaced evenly on a log scale between 3. and 10., exclusive." + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1.00000000e+03, 1.38038426e+03, 1.90546072e+03,\n", + " 2.63026799e+03, 3.63078055e+03, 5.01187234e+03,\n", + " 6.91830971e+03, 9.54992586e+03, 1.31825674e+04,\n", + " 1.81970086e+04, 2.51188643e+04, 3.46736850e+04,\n", + " 4.78630092e+04, 6.60693448e+04, 9.12010839e+04,\n", + " 1.25892541e+05, 1.73780083e+05, 2.39883292e+05,\n", + " 3.31131121e+05, 4.57088190e+05, 6.30957344e+05,\n", + " 8.70963590e+05, 1.20226443e+06, 1.65958691e+06,\n", + " 2.29086765e+06, 3.16227766e+06, 4.36515832e+06,\n", + " 6.02559586e+06, 8.31763771e+06, 1.14815362e+07,\n", + " 1.58489319e+07, 2.18776162e+07, 3.01995172e+07,\n", + " 4.16869383e+07, 5.75439937e+07, 7.94328235e+07,\n", + " 1.09647820e+08, 1.51356125e+08, 2.08929613e+08,\n", + " 2.88403150e+08, 3.98107171e+08, 5.49540874e+08,\n", + " 7.58577575e+08, 1.04712855e+09, 1.44543977e+09,\n", + " 1.99526231e+09, 2.75422870e+09, 3.80189396e+09,\n", + " 5.24807460e+09, 7.24435960e+09])" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.logspace(3., 10., 50, endpoint=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building matrices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let X = np.array([[ 0, 1, 2, 3],\n", + " [ 4, 5, 6, 7],\n", + " [ 8, 9, 10, 11]]).\n", + " Get the diagonal of X, that is, [0, 5, 10]." + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 5, 10])" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = np.array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])\n", + "np.diag(X)" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 5, 10])" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X.diagonal()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a 2-D array whose diagonal equals [1, 2, 3, 4] and 0's elsewhere." + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 0, 0, 0],\n", + " [0, 2, 0, 0],\n", + " [0, 0, 3, 0],\n", + " [0, 0, 0, 4]])" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.diagflat([1, 2, 3, 4])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array which looks like below.\n", + "array([[ 0., 0., 0., 0., 0.],\n", + " [ 1., 0., 0., 0., 0.],\n", + " [ 1., 1., 0., 0., 0.]])" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 0., 0., 0., 0.],\n", + " [ 1., 0., 0., 0., 0.],\n", + " [ 1., 1., 0., 0., 0.]])" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.tri(3, 5, -1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array which looks like below.\n", + "array([[ 0, 0, 0],\n", + " [ 4, 0, 0],\n", + " [ 7, 8, 0],\n", + " [10, 11, 12]])" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 0, 0],\n", + " [ 4, 0, 0],\n", + " [ 7, 8, 0],\n", + " [10, 11, 12]])" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.tril(np.arange(1, 13).reshape(4, 3), -1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create an array which looks like below. array([[ 1, 2, 3],\n", + " [ 4, 5, 6],\n", + " [ 0, 8, 9],\n", + " [ 0, 0, 12]])" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1, 2, 3],\n", + " [ 4, 5, 6],\n", + " [ 0, 8, 9],\n", + " [ 0, 0, 12]])" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.triu(np.arange(1, 13).reshape(4, 3), -1)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/2_Array_manipulation_routines.ipynb b/2_Array_manipulation_routines.ipynb new file mode 100644 index 0000000..85243a3 --- /dev/null +++ b/2_Array_manipulation_routines.ipynb @@ -0,0 +1,736 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Array manipulation routines" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Q1. Let x be a ndarray [10, 10, 3] with all elements set to one. Reshape x so that the size of the second dimension equals 150." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1.]\n", + " [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1.]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Let x be array [[1, 2, 3], [4, 5, 6]]. Convert it to [1 4 2 5 3 6]." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 4 2 5 3 6]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Let x be array [[1, 2, 3], [4, 5, 6]]. Get the 5th element." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Let x be an arbitrary 3-D array of shape (3, 4, 5). Permute the dimensions of x such that the new shape will be (4,3,5).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4L, 3L, 5L)\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Let x be an arbitrary 2-D array of shape (3, 4). Permute the dimensions of x such that the new shape will be (4,3)." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4L, 3L)\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Let x be an arbitrary 2-D array of shape (3, 4). Insert a nex axis such that the new shape will be (3, 1, 4)." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3L, 1L, 4L)\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Let x be an arbitrary 3-D array of shape (3, 4, 1). Remove a single-dimensional entries such that the new shape will be (3, 4)." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3L, 4L)\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Lex x be an array
\n", + "[[ 1 2 3]
\n", + "[ 4 5 6].

\n", + "and y be an array
\n", + "[[ 7 8 9]
\n", + "[10 11 12]].
\n", + "Concatenate x and y so that a new array looks like
[[1, 2, 3, 7, 8, 9],
[4, 5, 6, 10, 11, 12]].\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 2 3 7 8 9]\n", + " [ 4 5 6 10 11 12]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Lex x be an array
\n", + "[[ 1 2 3]
\n", + "[ 4 5 6].

\n", + "and y be an array
\n", + "[[ 7 8 9]
\n", + "[10 11 12]].
\n", + "Concatenate x and y so that a new array looks like
[[ 1 2 3]
\n", + " [ 4 5 6]
\n", + " [ 7 8 9]
\n", + " [10 11 12]]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 2 3]\n", + " [ 4 5 6]\n", + " [ 7 8 9]\n", + " [10 11 12]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Let x be an array [1 2 3] and y be [4 5 6]. Convert it to [[1, 4], [2, 5], [3, 6]]." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 4]\n", + " [2 5]\n", + " [3 6]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Let x be an array [[1],[2],[3]] and y be [[4], [5], [6]]. Convert x to [[[1, 4]], [[2, 5]], [[3, 6]]]." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[1 4]]\n", + "\n", + " [[2 5]]\n", + "\n", + " [[3 6]]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Let x be an array [1, 2, 3, ..., 9]. Split x into 3 arrays, each of which has 4, 2, and 3 elements in the original order." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([1, 2, 3, 4]), array([5, 6]), array([7, 8, 9])]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Let x be an array
\n", + "[[[ 0., 1., 2., 3.],
\n", + " [ 4., 5., 6., 7.]],
\n", + " \n", + " [[ 8., 9., 10., 11.],
\n", + " [ 12., 13., 14., 15.]]].
\n", + "Split it into two such that the first array looks like
\n", + "[[[ 0., 1., 2.],
\n", + " [ 4., 5., 6.]],
\n", + " \n", + " [[ 8., 9., 10.],
\n", + " [ 12., 13., 14.]]].
\n", + " \n", + "and the second one look like:
\n", + " \n", + "[[[ 3.],
\n", + " [ 7.]],
\n", + " \n", + " [[ 11.],
\n", + " [ 15.]]].
" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[[ 0, 1, 2],\n", + " [ 4, 5, 6]],\n", + "\n", + " [[ 8, 9, 10],\n", + " [12, 13, 14]]]), array([[[ 3],\n", + " [ 7]],\n", + "\n", + " [[11],\n", + " [15]]])]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Let x be an array
\n", + "[[ 0., 1., 2., 3.],
\n", + " [ 4., 5., 6., 7.],
\n", + " [ 8., 9., 10., 11.],
\n", + " [ 12., 13., 14., 15.]].
\n", + "Split it into two arrays along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[ 0, 1],\n", + " [ 4, 5],\n", + " [ 8, 9],\n", + " [12, 13]]), array([[ 2, 3],\n", + " [ 6, 7],\n", + " [10, 11],\n", + " [14, 15]])]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Let x be an array
\n", + "[[ 0., 1., 2., 3.],
\n", + " [ 4., 5., 6., 7.],
\n", + " [ 8., 9., 10., 11.],
\n", + " [ 12., 13., 14., 15.]].
\n", + "Split it into two arrays along the first axis." + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[0, 1, 2, 3],\n", + " [4, 5, 6, 7]]), array([[ 8, 9, 10, 11],\n", + " [12, 13, 14, 15]])]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Let x be an array [0, 1, 2]. Convert it to
\n", + "[[0, 1, 2, 0, 1, 2],
\n", + " [0, 1, 2, 0, 1, 2]]." + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 0 1 2]\n", + " [0 1 2 0 1 2]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Let x be an array [0, 1, 2]. Convert it to
\n", + "[0, 0, 1, 1, 2, 2]." + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 0 1 1 2 2]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q16. Let x be an array [0, 0, 0, 1, 2, 3, 0, 2, 1, 0].
\n", + "remove the leading the trailing zeros." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 3 0 2 1]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q17. Let x be an array [2, 2, 1, 5, 4, 5, 1, 2, 3]. Get two arrays of unique elements and their counts.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 3 4 5] [2 3 1 1 2]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q18. Lex x be an array
\n", + "[[ 1 2]
\n", + " [ 3 4].
\n", + "Flip x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[2 1]\n", + " [4 3]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q19. Lex x be an array
\n", + "[[ 1 2]
\n", + " [ 3 4].
\n", + "Flip x along the first axis." + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[3 4]\n", + " [1 2]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q20. Lex x be an array
\n", + "[[ 1 2]
\n", + " [ 3 4].
\n", + "Rotate x 90 degrees counter-clockwise." + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[2 4]\n", + " [1 3]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q21 Lex x be an array
\n", + "[[ 1 2 3 4]
\n", + " [ 5 6 7 8].
\n", + "Shift elements one step to right along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[4 1 2 3]\n", + " [8 5 6 7]]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/2_Array_manipulation_routines_Solutions.ipynb b/2_Array_manipulation_routines_Solutions.ipynb new file mode 100644 index 0000000..49584ee --- /dev/null +++ b/2_Array_manipulation_routines_Solutions.ipynb @@ -0,0 +1,860 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Array manipulation routines" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "Q1. Let x be a ndarray [10, 10, 3] with all elements set to one. Reshape x so that the size of the second dimension equals 150." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1.]\n", + " [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.\n", + " 1. 1. 1. 1. 1. 1.]]\n" + ] + } + ], + "source": [ + "x = np.ones([10, 10, 3])\n", + "out = np.reshape(x, [-1, 150])\n", + "print out\n", + "assert np.allclose(out, np.ones([10, 10, 3]).reshape([-1, 150]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Let x be array [[1, 2, 3], [4, 5, 6]]. Convert it to [1 4 2 5 3 6]." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 4 2 5 3 6]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "out1 = np.ravel(x, order='F')\n", + "out2 = x.flatten(order=\"F\")\n", + "assert np.allclose(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Let x be array [[1, 2, 3], [4, 5, 6]]. Get the 5th element." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "out1 = x.flat[4]\n", + "out2 = np.ravel(x)[4]\n", + "assert np.allclose(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Let x be an arbitrary 3-D array of shape (3, 4, 5). Permute the dimensions of x such that the new shape will be (4,3,5).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4L, 3L, 5L)\n" + ] + } + ], + "source": [ + "x = np.zeros((3, 4, 5))\n", + "out1 = np.swapaxes(x, 1, 0)\n", + "out2 = x.transpose([1, 0, 2])\n", + "assert out1.shape == out2.shape\n", + "print out1.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Let x be an arbitrary 2-D array of shape (3, 4). Permute the dimensions of x such that the new shape will be (4,3)." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4L, 3L)\n" + ] + } + ], + "source": [ + "x = np.zeros((3, 4))\n", + "out1 = np.swapaxes(x, 1, 0)\n", + "out2 = x.transpose()\n", + "out3 = x.T\n", + "assert out1.shape == out2.shape == out3.shape\n", + "print out1.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Let x be an arbitrary 2-D array of shape (3, 4). Insert a nex axis such that the new shape will be (3, 1, 4)." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3L, 1L, 4L)\n" + ] + } + ], + "source": [ + "x = np.zeros((3, 4))\n", + "print np.expand_dims(x, axis=1).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Let x be an arbitrary 3-D array of shape (3, 4, 1). Remove a single-dimensional entries such that the new shape will be (3, 4)." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3L, 4L)\n" + ] + } + ], + "source": [ + "x = np.zeros((3, 4, 1))\n", + "print np.squeeze(x).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Lex x be an array
\n", + "[[ 1 2 3]
\n", + "[ 4 5 6].

\n", + "and y be an array
\n", + "[[ 7 8 9]
\n", + "[10 11 12]].
\n", + "Concatenate x and y so that a new array looks like
[[1, 2, 3, 7, 8, 9],
[4, 5, 6, 10, 11, 12]].\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 2 3 7 8 9]\n", + " [ 4 5 6 10 11 12]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "out1 = np.concatenate((x, y), 1)\n", + "out2 = np.hstack((x, y))\n", + "assert np.allclose(out1, out2)\n", + "print out2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Lex x be an array
\n", + "[[ 1 2 3]
\n", + "[ 4 5 6].

\n", + "and y be an array
\n", + "[[ 7 8 9]
\n", + "[10 11 12]].
\n", + "Concatenate x and y so that a new array looks like
[[ 1 2 3]
\n", + " [ 4 5 6]
\n", + " [ 7 8 9]
\n", + " [10 11 12]]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 2 3]\n", + " [ 4 5 6]\n", + " [ 7 8 9]\n", + " [10 11 12]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "out1 = np.concatenate((x, y), 0)\n", + "out2 = np.vstack((x, y))\n", + "assert np.allclose(out1, out2)\n", + "print out2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Let x be an array [1 2 3] and y be [4 5 6]. Convert it to [[1, 4], [2, 5], [3, 6]]." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 4]\n", + " [2 5]\n", + " [3 6]]\n" + ] + } + ], + "source": [ + "x = np.array((1,2,3))\n", + "y = np.array((4,5,6))\n", + "out1 = np.column_stack((x, y))\n", + "out2 = np.dstack((x, y))\n", + "out3 = np.vstack((x, y)).T\n", + "assert np.allclose(out1, out2)\n", + "assert np.allclose(out2, out3)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Let x be an array [[1],[2],[3]] and y be [[4], [5], [6]]. Convert x to [[[1, 4]], [[2, 5]], [[3, 6]]]." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[1 4]]\n", + "\n", + " [[2 5]]\n", + "\n", + " [[3 6]]]\n" + ] + } + ], + "source": [ + "x = np.array([[1],[2],[3]])\n", + "y = np.array([[4],[5],[6]])\n", + "out = np.dstack((x, y))\n", + "print out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Let x be an array [1, 2, 3, ..., 9]. Split x into 3 arrays, each of which has 4, 2, and 3 elements in the original order." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([1, 2, 3, 4]), array([5, 6]), array([7, 8, 9])]\n" + ] + } + ], + "source": [ + "x = np.arange(1, 10)\n", + "print np.split(x, [4, 6])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Let x be an array
\n", + "[[[ 0., 1., 2., 3.],
\n", + " [ 4., 5., 6., 7.]],
\n", + " \n", + " [[ 8., 9., 10., 11.],
\n", + " [ 12., 13., 14., 15.]]].
\n", + "Split it into two such that the first array looks like
\n", + "[[[ 0., 1., 2.],
\n", + " [ 4., 5., 6.]],
\n", + " \n", + " [[ 8., 9., 10.],
\n", + " [ 12., 13., 14.]]].
\n", + " \n", + "and the second one look like:
\n", + " \n", + "[[[ 3.],
\n", + " [ 7.]],
\n", + " \n", + " [[ 11.],
\n", + " [ 15.]]].
" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[[ 0, 1, 2],\n", + " [ 4, 5, 6]],\n", + "\n", + " [[ 8, 9, 10],\n", + " [12, 13, 14]]]), array([[[ 3],\n", + " [ 7]],\n", + "\n", + " [[11],\n", + " [15]]])]\n" + ] + } + ], + "source": [ + "x = np.arange(16).reshape(2, 2, 4)\n", + "out1 = np.split(x, [3],axis=2)\n", + "out2 = np.dsplit(x, [3])\n", + "assert np.allclose(out1[0], out2[0])\n", + "assert np.allclose(out1[1], out2[1])\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Let x be an array
\n", + "[[ 0., 1., 2., 3.],
\n", + " [ 4., 5., 6., 7.],
\n", + " [ 8., 9., 10., 11.],
\n", + " [ 12., 13., 14., 15.]].
\n", + "Split it into two arrays along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[ 0, 1],\n", + " [ 4, 5],\n", + " [ 8, 9],\n", + " [12, 13]]), array([[ 2, 3],\n", + " [ 6, 7],\n", + " [10, 11],\n", + " [14, 15]])]\n" + ] + } + ], + "source": [ + "x = np.arange(16).reshape((4, 4))\n", + "out1 = np.hsplit(x, 2)\n", + "out2 = np.split(x, 2, 1)\n", + "assert np.allclose(out1[0], out2[0])\n", + "assert np.allclose(out1[1], out2[1])\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Let x be an array
\n", + "[[ 0., 1., 2., 3.],
\n", + " [ 4., 5., 6., 7.],
\n", + " [ 8., 9., 10., 11.],
\n", + " [ 12., 13., 14., 15.]].
\n", + "Split it into two arrays along the first axis." + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[0, 1, 2, 3],\n", + " [4, 5, 6, 7]]), array([[ 8, 9, 10, 11],\n", + " [12, 13, 14, 15]])]\n" + ] + } + ], + "source": [ + "x = np.arange(16).reshape((4, 4))\n", + "out1 = np.vsplit(x, 2)\n", + "out2 = np.split(x, 2, 0)\n", + "assert np.allclose(out1[0], out2[0])\n", + "assert np.allclose(out1[1], out2[1])\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Let x be an array [0, 1, 2]. Convert it to
\n", + "[[0, 1, 2, 0, 1, 2],
\n", + " [0, 1, 2, 0, 1, 2]]." + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 0 1 2]\n", + " [0 1 2 0 1 2]]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2])\n", + "out1 = np.tile(x, [2, 2])\n", + "out2 = np.resize(x, [2, 6])\n", + "assert np.allclose(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Let x be an array [0, 1, 2]. Convert it to
\n", + "[0, 0, 1, 1, 2, 2]." + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 0 1 1 2 2]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2])\n", + "print np.repeat(x, 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q16. Let x be an array [0, 0, 0, 1, 2, 3, 0, 2, 1, 0].
\n", + "remove the leading the trailing zeros." + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 3 0 2 1]\n" + ] + } + ], + "source": [ + "x = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0))\n", + "out = np.trim_zeros(x)\n", + "print out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q17. Let x be an array [2, 2, 1, 5, 4, 5, 1, 2, 3]. Get two arrays of unique elements and their counts.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 3 4 5] [2 3 1 1 2]\n" + ] + } + ], + "source": [ + "x = np.array([2, 2, 1, 5, 4, 5, 1, 2, 3])\n", + "u, indices = np.unique(x, return_counts=True)\n", + "print u, indices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q18. Lex x be an array
\n", + "[[ 1 2]
\n", + " [ 3 4].
\n", + "Flip x along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[2 1]\n", + " [4 3]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2], [3,4]])\n", + "out1 = np.fliplr(x)\n", + "out2 = x[:, ::-1]\n", + "assert np.allclose(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q19. Lex x be an array
\n", + "[[ 1 2]
\n", + " [ 3 4].
\n", + "Flip x along the first axis." + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[3 4]\n", + " [1 2]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2], [3,4]])\n", + "out1 = np.flipud(x)\n", + "out2 = x[::-1, :]\n", + "assert np.allclose(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q20. Lex x be an array
\n", + "[[ 1 2]
\n", + " [ 3 4].
\n", + "Rotate x 90 degrees counter-clockwise." + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[2 4]\n", + " [1 3]]\n" + ] + } + ], + "source": [ + "x = np.array([[1,2], [3,4]])\n", + "out = np.rot90(x)\n", + "print out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q21 Lex x be an array
\n", + "[[ 1 2 3 4]
\n", + " [ 5 6 7 8].
\n", + "Shift elements one step to right along the second axis." + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[4 1 2 3]\n", + " [8 5 6 7]]\n" + ] + } + ], + "source": [ + "x = np.arange(1, 9).reshape([2, 4])\n", + "print np.roll(x, 1, axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/3_String_operations.ipynb b/3_String_operations.ipynb new file mode 100644 index 0000000..73b5ee8 --- /dev/null +++ b/3_String_operations.ipynb @@ -0,0 +1,601 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## String operations" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = \"kyubyong. https://github.com/Kyubyong/numpy_exercises\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.3'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Concatenate x1 and x2." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Hello world' 'Say something']\n" + ] + } + ], + "source": [ + "x1 = np.array(['Hello', 'Say'], dtype=np.str)\n", + "x2 = np.array([' world', ' something'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Repeat x three time element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Hello Hello Hello ' 'Say Say Say ']\n" + ] + } + ], + "source": [ + "x = np.array(['Hello ', 'Say '], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3-1. Capitalize the first letter of x element-wise.
\n", + "Q3-2. Lowercase x element-wise.
\n", + "Q3-3. Uppercase x element-wise.
\n", + "Q3-4. Swapcase x element-wise.
\n", + "Q3-5. Title-case x element-wise.
" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "capitalized = ['Hello world' 'Say something']\n", + "lowered = ['hello world' 'say something']\n", + "uppered = ['HELLO WORLD' 'SAY SOMETHING']\n", + "swapcased = ['HEllO WOrlD' 'sAY SoMETHING']\n", + "titlecased = ['Hello World' 'Say Something']\n" + ] + } + ], + "source": [ + "x = np.array(['heLLo woRLd', 'Say sOmething'], dtype=np.str)\n", + "capitalized = ...\n", + "lowered = ...\n", + "uppered = ...\n", + "swapcased = ...\n", + "titlecased = ...\n", + "print(\"capitalized =\", capitalized)\n", + "print(\"lowered =\", lowered)\n", + "print(\"uppered =\", uppered)\n", + "print(\"swapcased =\", swapcased)\n", + "print(\"titlecased =\", titlecased)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Make the length of each element 20 and the string centered / left-justified / right-justified with paddings of `_`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "centered = ['____hello world_____' '___say something____']\n", + "left = ['hello world_________' 'say something_______']\n", + "right = ['_________hello world' '_______say something']\n" + ] + } + ], + "source": [ + "x = np.array(['hello world', 'say something'], dtype=np.str)\n", + "centered = ...\n", + "left = ...\n", + "right = ...\n", + "\n", + "print(\"centered =\", centered)\n", + "print(\"left =\", left)\n", + "print(\"right =\", right)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Encode x in cp500 and decode it again." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "encoded = [b'\\x88\\x85\\x93\\x93\\x96@\\xa6\\x96\\x99\\x93\\x84'\n", + " b'\\xa2\\x81\\xa8@\\xa2\\x96\\x94\\x85\\xa3\\x88\\x89\\x95\\x87']\n", + "decoded = ['hello world' 'say something']\n" + ] + } + ], + "source": [ + "x = np.array(['hello world', 'say something'], dtype=np.str)\n", + "encoded = ...\n", + "decoded = ...\n", + "print(\"encoded =\", encoded)\n", + "print(\"decoded =\", decoded)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Insert a space between characters of x." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['h e l l o w o r l d' 's a y s o m e t h i n g']\n" + ] + } + ], + "source": [ + "x = np.array(['hello world', 'say something'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7-1. Remove the leading and trailing whitespaces of x element-wise.
\n", + "Q7-2. Remove the leading whitespaces of x element-wise.
\n", + "Q7-3. Remove the trailing whitespaces of x element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "stripped = ['hello world' 'say something']\n", + "lstripped = ['hello world ' 'say something\\n']\n", + "rstripped = [' hello world' '\\tsay something']\n" + ] + } + ], + "source": [ + "x = np.array([' hello world ', '\\tsay something\\n'], dtype=np.str)\n", + "stripped = ...\n", + "lstripped = ...\n", + "rstripped = ...\n", + "print(\"stripped =\", stripped)\n", + "print(\"lstripped =\", lstripped)\n", + "print(\"rstripped =\", rstripped)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Split the element of x with spaces." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[['Hello', 'my', 'name', 'is', 'John']]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello my name is John'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Split the element of x to multiple lines." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[['Hello', 'my name is John']]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello\\nmy name is John'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Make x a numeric string of 4 digits with zeros on its left." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['0034']\n" + ] + } + ], + "source": [ + "x = np.array(['34'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Replace \"John\" with \"Jim\" in x." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Hello nmy name is Jim']\n" + ] + } + ], + "source": [ + "x = np.array(['Hello nmy name is John'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Return x1 == x2, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True True True False]\n" + ] + } + ], + "source": [ + "x1 = np.array(['Hello', 'my', 'name', 'is', 'John'], dtype=np.str)\n", + "x2 = np.array(['Hello', 'my', 'name', 'is', 'Jim'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Return x1 != x2, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[False False False False True]\n" + ] + } + ], + "source": [ + "x1 = np.array(['Hello', 'my', 'name', 'is', 'John'], dtype=np.str)\n", + "x2 = np.array(['Hello', 'my', 'name', 'is', 'Jim'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## String information" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Count the number of \"l\" in x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 0 0 0 1]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello', 'my', 'name', 'is', 'Lily'], dtype=np.str)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Count the lowest index of \"l\" in x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2 -1 -1 -1 2]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello', 'my', 'name', 'is', 'Lily'], dtype=np.str)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q16-1. Check if each element of x is composed of digits only.
\n", + "Q16-2. Check if each element of x is composed of lower case letters only.
\n", + "Q16-3. Check if each element of x is composed of upper case letters only." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Digits only = [False False False True False False]\n", + "Lower cases only = [False False True False True True]\n", + "Upper cases only = [False True False False False False]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello', 'I', 'am', '20', 'years', 'old'], dtype=np.str)\n", + "out1 = ...\n", + "out2 = ...\n", + "out3 = ...\n", + "print(\"Digits only =\", out1)\n", + "print(\"Lower cases only =\", out2)\n", + "print(\"Upper cases only =\", out3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q17. Check if each element of x starts with \"hi\"." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[False True True True]\n" + ] + } + ], + "source": [ + "x = np.array(['he', 'his', 'him', 'his'], dtype=np.str)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [conda root]", + "language": "python", + "name": "conda-root-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/3_String_operations_solutions.ipynb b/3_String_operations_solutions.ipynb new file mode 100644 index 0000000..9c0f8d4 --- /dev/null +++ b/3_String_operations_solutions.ipynb @@ -0,0 +1,627 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## String operations" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = \"kyubyong. https://github.com/Kyubyong/numpy_exercises\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.3'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Concatenate x1 and x2." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Hello world' 'Say something']\n" + ] + } + ], + "source": [ + "x1 = np.array(['Hello', 'Say'], dtype=np.str)\n", + "x2 = np.array([' world', ' something'], dtype=np.str)\n", + "out = np.char.add(x1, x2)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Repeat x three time element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Hello Hello Hello ' 'Say Say Say ']\n" + ] + } + ], + "source": [ + "x = np.array(['Hello ', 'Say '], dtype=np.str)\n", + "out = np.char.multiply(x, 3)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3-1. Capitalize the first letter of x element-wise.
\n", + "Q3-2. Lowercase x element-wise.
\n", + "Q3-3. Uppercase x element-wise.
\n", + "Q3-4. Swapcase x element-wise.
\n", + "Q3-5. Title-case x element-wise.
" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "capitalized = ['Hello world' 'Say something']\n", + "lowered = ['hello world' 'say something']\n", + "uppered = ['HELLO WORLD' 'SAY SOMETHING']\n", + "swapcased = ['HEllO WOrlD' 'sAY SoMETHING']\n", + "titlecased = ['Hello World' 'Say Something']\n" + ] + } + ], + "source": [ + "x = np.array(['heLLo woRLd', 'Say sOmething'], dtype=np.str)\n", + "capitalized = np.char.capitalize(x)\n", + "lowered = np.char.lower(x)\n", + "uppered = np.char.upper(x)\n", + "swapcased = np.char.swapcase(x)\n", + "titlecased = np.char.title(x)\n", + "print(\"capitalized =\", capitalized)\n", + "print(\"lowered =\", lowered)\n", + "print(\"uppered =\", uppered)\n", + "print(\"swapcased =\", swapcased)\n", + "print(\"titlecased =\", titlecased)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Make the length of each element 20 and the string centered / left-justified / right-justified with paddings of `_`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "centered = ['____hello world_____' '___say something____']\n", + "left = ['hello world_________' 'say something_______']\n", + "right = ['_________hello world' '_______say something']\n" + ] + } + ], + "source": [ + "x = np.array(['hello world', 'say something'], dtype=np.str)\n", + "centered = np.char.center(x, 20, fillchar='_')\n", + "left = np.char.ljust(x, 20, fillchar='_')\n", + "right = np.char.rjust(x, 20, fillchar='_')\n", + "\n", + "print(\"centered =\", centered)\n", + "print(\"left =\", left)\n", + "print(\"right =\", right)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Encode x in cp500 and decode it again." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "encoded = [b'\\x88\\x85\\x93\\x93\\x96@\\xa6\\x96\\x99\\x93\\x84'\n", + " b'\\xa2\\x81\\xa8@\\xa2\\x96\\x94\\x85\\xa3\\x88\\x89\\x95\\x87']\n", + "decoded = ['hello world' 'say something']\n" + ] + } + ], + "source": [ + "x = np.array(['hello world', 'say something'], dtype=np.str)\n", + "encoded = np.char.encode(x, 'cp500')\n", + "decoded = np.char.decode(encoded,'cp500')\n", + "print(\"encoded =\", encoded)\n", + "print(\"decoded =\", decoded)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Insert a space between characters of x." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['h e l l o w o r l d' 's a y s o m e t h i n g']\n" + ] + } + ], + "source": [ + "x = np.array(['hello world', 'say something'], dtype=np.str)\n", + "out = np.char.join(\" \", x)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7-1. Remove the leading and trailing whitespaces of x element-wise.
\n", + "Q7-2. Remove the leading whitespaces of x element-wise.
\n", + "Q7-3. Remove the trailing whitespaces of x element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "stripped = ['hello world' 'say something']\n", + "lstripped = ['hello world ' 'say something\\n']\n", + "rstripped = [' hello world' '\\tsay something']\n" + ] + } + ], + "source": [ + "x = np.array([' hello world ', '\\tsay something\\n'], dtype=np.str)\n", + "stripped = np.char.strip(x)\n", + "lstripped = np.char.lstrip(x)\n", + "rstripped = np.char.rstrip(x)\n", + "print(\"stripped =\", stripped)\n", + "print(\"lstripped =\", lstripped)\n", + "print(\"rstripped =\", rstripped)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Split the element of x with spaces." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[['Hello', 'my', 'name', 'is', 'John']]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello my name is John'], dtype=np.str)\n", + "out = np.char.split(x)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Split the element of x to multiple lines." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[['Hello', 'my name is John']]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello\\nmy name is John'], dtype=np.str)\n", + "out = np.char.splitlines(x)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Make x a numeric string of 4 digits with zeros on its left." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['0034']\n" + ] + } + ], + "source": [ + "x = np.array(['34'], dtype=np.str)\n", + "out = np.char.zfill(x, 4)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Replace \"John\" with \"Jim\" in x." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Hello nmy name is Jim']\n" + ] + } + ], + "source": [ + "x = np.array(['Hello nmy name is John'], dtype=np.str)\n", + "out = np.char.replace(x, \"John\", \"Jim\")\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Return x1 == x2, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True True True False]\n" + ] + } + ], + "source": [ + "x1 = np.array(['Hello', 'my', 'name', 'is', 'John'], dtype=np.str)\n", + "x2 = np.array(['Hello', 'my', 'name', 'is', 'Jim'], dtype=np.str)\n", + "out = np.char.equal(x1, x2)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Return x1 != x2, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[False False False False True]\n" + ] + } + ], + "source": [ + "x1 = np.array(['Hello', 'my', 'name', 'is', 'John'], dtype=np.str)\n", + "x2 = np.array(['Hello', 'my', 'name', 'is', 'Jim'], dtype=np.str)\n", + "out = np.char.not_equal(x1, x2)\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## String information" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Count the number of \"l\" in x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 0 0 0 1]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello', 'my', 'name', 'is', 'Lily'], dtype=np.str)\n", + "out = np.char.count(x, \"l\")\n", + "print(out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Count the lowest index of \"l\" in x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2 -1 -1 -1 2]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello', 'my', 'name', 'is', 'Lily'], dtype=np.str)\n", + "out = np.char.find(x, \"l\")\n", + "print(out)\n", + "\n", + "# compare\n", + "# print(np.char.index(x, \"l\"))\n", + "# => This raises an error!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q16-1. Check if each element of x is composed of digits only.
\n", + "Q16-2. Check if each element of x is composed of lower case letters only.
\n", + "Q16-3. Check if each element of x is composed of upper case letters only." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Digits only = [False False False True False False]\n", + "Lower cases only = [False False True False True True]\n", + "Upper cases only = [False True False False False False]\n" + ] + } + ], + "source": [ + "x = np.array(['Hello', 'I', 'am', '20', 'years', 'old'], dtype=np.str)\n", + "out1 = np.char.isdigit(x)\n", + "out2 = np.char.islower(x)\n", + "out3 = np.char.isupper(x)\n", + "print(\"Digits only =\", out1)\n", + "print(\"Lower cases only =\", out2)\n", + "print(\"Upper cases only =\", out3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q17. Check if each element of x starts with \"hi\"." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[False True True True]\n" + ] + } + ], + "source": [ + "x = np.array(['he', 'his', 'him', 'his'], dtype=np.str)\n", + "out = np.char.startswith(x, \"hi\")\n", + "print(out)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [conda root]", + "language": "python", + "name": "conda-root-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/4_Numpy-specific_help_functions.ipynb b/4_Numpy-specific_help_functions.ipynb new file mode 100644 index 0000000..b4a2b2f --- /dev/null +++ b/4_Numpy-specific_help_functions.ipynb @@ -0,0 +1,201 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Search for docstrings of the numpy functions on linear algebra." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Search results for 'linear algebra'\n", + "-----------------------------------\n", + "numpy.linalg.solve\n", + " Solve a linear matrix equation, or system of linear scalar equations.\n", + "numpy.poly\n", + " Find the coefficients of a polynomial with the given sequence of roots.\n", + "numpy.restoredot\n", + " Restore `dot`, `vdot`, and `innerproduct` to the default non-BLAS\n", + "numpy.linalg.eig\n", + " Compute the eigenvalues and right eigenvectors of a square array.\n", + "numpy.linalg.cond\n", + " Compute the condition number of a matrix.\n", + "numpy.linalg.eigh\n", + " Return the eigenvalues and eigenvectors of a Hermitian or symmetric matrix.\n", + "numpy.linalg.pinv\n", + " Compute the (Moore-Penrose) pseudo-inverse of a matrix.\n", + "numpy.linalg.LinAlgError\n", + " Generic Python-exception-derived object raised by linalg functions.\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Get help information for numpy dot function." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dot(a, b, out=None)\n", + "\n", + "Dot product of two arrays.\n", + "\n", + "For 2-D arrays it is equivalent to matrix multiplication, and for 1-D\n", + "arrays to inner product of vectors (without complex conjugation). For\n", + "N dimensions it is a sum product over the last axis of `a` and\n", + "the second-to-last of `b`::\n", + "\n", + " dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])\n", + "\n", + "Parameters\n", + "----------\n", + "a : array_like\n", + " First argument.\n", + "b : array_like\n", + " Second argument.\n", + "out : ndarray, optional\n", + " Output argument. This must have the exact kind that would be returned\n", + " if it was not used. In particular, it must have the right type, must be\n", + " C-contiguous, and its dtype must be the dtype that would be returned\n", + " for `dot(a,b)`. This is a performance feature. Therefore, if these\n", + " conditions are not met, an exception is raised, instead of attempting\n", + " to be flexible.\n", + "\n", + "Returns\n", + "-------\n", + "output : ndarray\n", + " Returns the dot product of `a` and `b`. If `a` and `b` are both\n", + " scalars or both 1-D arrays then a scalar is returned; otherwise\n", + " an array is returned.\n", + " If `out` is given, then it is returned.\n", + "\n", + "Raises\n", + "------\n", + "ValueError\n", + " If the last dimension of `a` is not the same size as\n", + " the second-to-last dimension of `b`.\n", + "\n", + "See Also\n", + "--------\n", + "vdot : Complex-conjugating dot product.\n", + "tensordot : Sum products over arbitrary axes.\n", + "einsum : Einstein summation convention.\n", + "matmul : '@' operator as method with out parameter.\n", + "\n", + "Examples\n", + "--------\n", + ">>> np.dot(3, 4)\n", + "12\n", + "\n", + "Neither argument is complex-conjugated:\n", + "\n", + ">>> np.dot([2j, 3j], [2j, 3j])\n", + "(-13+0j)\n", + "\n", + "For 2-D arrays it is the matrix product:\n", + "\n", + ">>> a = [[1, 0], [0, 1]]\n", + ">>> b = [[4, 1], [2, 2]]\n", + ">>> np.dot(a, b)\n", + "array([[4, 1],\n", + " [2, 2]])\n", + "\n", + ">>> a = np.arange(3*4*5*6).reshape((3,4,5,6))\n", + ">>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))\n", + ">>> np.dot(a, b)[2,3,2,1,2,2]\n", + "499128\n", + ">>> sum(a[2,3,2,:] * b[1,2,:,2])\n", + "499128\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/4_Numpy-specific_help_functions_Solutions.ipynb b/4_Numpy-specific_help_functions_Solutions.ipynb new file mode 100644 index 0000000..bf01235 --- /dev/null +++ b/4_Numpy-specific_help_functions_Solutions.ipynb @@ -0,0 +1,205 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Search for docstrings of the numpy functions on linear algebra." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Search results for 'linear algebra'\n", + "-----------------------------------\n", + "numpy.linalg.solve\n", + " Solve a linear matrix equation, or system of linear scalar equations.\n", + "numpy.poly\n", + " Find the coefficients of a polynomial with the given sequence of roots.\n", + "numpy.restoredot\n", + " Restore `dot`, `vdot`, and `innerproduct` to the default non-BLAS\n", + "numpy.linalg.eig\n", + " Compute the eigenvalues and right eigenvectors of a square array.\n", + "numpy.linalg.cond\n", + " Compute the condition number of a matrix.\n", + "numpy.linalg.eigh\n", + " Return the eigenvalues and eigenvectors of a Hermitian or symmetric matrix.\n", + "numpy.linalg.pinv\n", + " Compute the (Moore-Penrose) pseudo-inverse of a matrix.\n", + "numpy.linalg.LinAlgError\n", + " Generic Python-exception-derived object raised by linalg functions.\n" + ] + } + ], + "source": [ + "np.lookfor('linear algebra')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Get help information for numpy dot function." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dot(a, b, out=None)\n", + "\n", + "Dot product of two arrays.\n", + "\n", + "For 2-D arrays it is equivalent to matrix multiplication, and for 1-D\n", + "arrays to inner product of vectors (without complex conjugation). For\n", + "N dimensions it is a sum product over the last axis of `a` and\n", + "the second-to-last of `b`::\n", + "\n", + " dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])\n", + "\n", + "Parameters\n", + "----------\n", + "a : array_like\n", + " First argument.\n", + "b : array_like\n", + " Second argument.\n", + "out : ndarray, optional\n", + " Output argument. This must have the exact kind that would be returned\n", + " if it was not used. In particular, it must have the right type, must be\n", + " C-contiguous, and its dtype must be the dtype that would be returned\n", + " for `dot(a,b)`. This is a performance feature. Therefore, if these\n", + " conditions are not met, an exception is raised, instead of attempting\n", + " to be flexible.\n", + "\n", + "Returns\n", + "-------\n", + "output : ndarray\n", + " Returns the dot product of `a` and `b`. If `a` and `b` are both\n", + " scalars or both 1-D arrays then a scalar is returned; otherwise\n", + " an array is returned.\n", + " If `out` is given, then it is returned.\n", + "\n", + "Raises\n", + "------\n", + "ValueError\n", + " If the last dimension of `a` is not the same size as\n", + " the second-to-last dimension of `b`.\n", + "\n", + "See Also\n", + "--------\n", + "vdot : Complex-conjugating dot product.\n", + "tensordot : Sum products over arbitrary axes.\n", + "einsum : Einstein summation convention.\n", + "matmul : '@' operator as method with out parameter.\n", + "\n", + "Examples\n", + "--------\n", + ">>> np.dot(3, 4)\n", + "12\n", + "\n", + "Neither argument is complex-conjugated:\n", + "\n", + ">>> np.dot([2j, 3j], [2j, 3j])\n", + "(-13+0j)\n", + "\n", + "For 2-D arrays it is the matrix product:\n", + "\n", + ">>> a = [[1, 0], [0, 1]]\n", + ">>> b = [[4, 1], [2, 2]]\n", + ">>> np.dot(a, b)\n", + "array([[4, 1],\n", + " [2, 2]])\n", + "\n", + ">>> a = np.arange(3*4*5*6).reshape((3,4,5,6))\n", + ">>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))\n", + ">>> np.dot(a, b)[2,3,2,1,2,2]\n", + "499128\n", + ">>> sum(a[2,3,2,:] * b[1,2,:,2])\n", + "499128\n" + ] + } + ], + "source": [ + "np.info(np.dot)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/5_Input_and_Output.ipynb b/5_Input_and_Output.ipynb new file mode 100644 index 0000000..e3edc16 --- /dev/null +++ b/5_Input_and_Output.ipynb @@ -0,0 +1,518 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Input and Output" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = \"kyubyong. https://github.com/Kyubyong/numpy_exercises\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.12.0'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2017-04-01\n" + ] + } + ], + "source": [ + "from datetime import date\n", + "print(date.today())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## NumPy binary files (NPY, NPZ)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Save x into `temp.npy` and load it." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n", + "...\n", + "\n", + "# Check if there exists the 'temp.npy' file.\n", + "import os\n", + "if os.path.exists('temp.npy'):\n", + " x2 = ...\n", + " print(np.array_equal(x, x2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Save x and y into a single file 'temp.npz' and load it." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n", + "y = np.arange(11, 20)\n", + "...\n", + "\n", + "with ... as data:\n", + " x2 = data['x']\n", + " y2 = data['y']\n", + " print(np.array_equal(x, x2))\n", + " print(np.array_equal(y, y2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Text files" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Save x to 'temp.txt' in string format and load it." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 1., 2., 3., 4.],\n", + " [ 5., 6., 7., 8., 9.]])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(10).reshape(2, 5)\n", + "header = 'num1 num2 num3 num4 num5'\n", + "...\n", + "..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Save `x`, `y`, and `z` to 'temp.txt' in string format line by line, then load it." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],\n", + " [ 11., 12., 13., 14., 15., 16., 17., 18., 19., 20.],\n", + " [ 22., 23., 24., 25., 26., 27., 28., 29., 30., 31.]])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(10)\n", + "y = np.arange(11, 21)\n", + "z = np.arange(22, 32)\n", + "...\n", + "..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Convert `x` into bytes, and load it as array." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3, 4])\n", + "x_bytes = ...\n", + "x2 = ...\n", + "print(np.array_equal(x, x2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Convert `a` into an ndarray and then convert it into a list again." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "a = [[1, 2], [3, 4]]\n", + "x = ...\n", + "a2 = ...\n", + "print(a == a2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## String formatting¶" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Convert `x` to a string, and revert it." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]] \n", + " \n" + ] + } + ], + "source": [ + "x = np.arange(10).reshape(2,5)\n", + "x_str = ...\n", + "print(x_str, \"\\n\", type(x_str))\n", + "x_str = x_str.replace(\"[\", \"\") # [] must be stripped\n", + "x_str = x_str.replace(\"]\", \"\")\n", + "x2 = ...\n", + "assert np.array_equal(x, x2)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Text formatting options" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Print `x` such that all elements are displayed with precision=1, no suppress." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.8 0.5 0.9 0. 0.6 0.6 0.5 0.5 0.9 0.9 0.3 0.6 0.9 0.8\n", + " 0.1 0.5 0.3 0.9 0.1 0.8 0.3 0. 0.4 0.5 0.4 0.6 0.2 0.6\n", + " 0.6 0.5 0.7 0.4 0.1 0.6 0.7 0.3 0.1 0.5 0.1 0.5 0. 0.8 1.\n", + " 0.5 0.3 0.9 0.3 0.6 0.9 0. 0.4 0.5 0.9 0.3 0.9 0.2 0.9\n", + " 0.4 0.8 0.5 0.2 0.1 0.2 0.7 0.6 0.3 0.6 0.8 0.7 0.2 0.2\n", + " 0.4 0.6 0.4 1. 0. 0.2 0.4 0.8 0.5 0.4 0.4 0.6 0.2 0.2\n", + " 0.8 0.1 0.9 0.7 0.3 1. 0.6 0.7 0.4 0.1 0.9 0.2 0.4 0.1\n", + " 0.3]\n", + " [ 0.5 0.9 0.2 0.1 0. 0.4 0.5 0.3 0.5 0.8 0.2 0.5 0.9 0.4\n", + " 0.2 0.8 0.3 0.1 0.8 0.5 0.2 0. 0.7 0.7 0.6 0.7 0.1 0.2\n", + " 0.6 0.2 0.4 0.2 0.2 0.1 0.4 0.4 0.9 0.6 0.3 0.4 0.9 0.1\n", + " 0.6 0.7 0.7 0.2 0.5 0.3 0.3 0.8 0. 0.1 0.3 0.9 0.8 0.9\n", + " 0.3 0.5 0.5 0.7 0.5 0.8 0.2 0.9 0.1 1. 0.5 0.3 0.7 0.2\n", + " 0.9 0.3 0.6 0.4 1. 0.2 1. 0.7 0.8 0.6 0.9 0.9 0.4 1. 0.3\n", + " 0.7 0. 0.3 0.2 0.4 0.1 0.6 0.2 0.4 0.7 0.3 0. 0.7 0.1\n", + " 0.5]\n", + " [ 0.7 0.1 0.6 0.2 0.9 0.8 0.5 0.6 0.9 0.8 0.4 0.1 0.1 0.7\n", + " 0.7 0.8 0.1 0.8 0.4 0.2 0.6 0.8 1. 0.8 0.6 0.8 0.3 0.1\n", + " 0.5 0.5 0.4 0.2 0.8 0.4 0.4 0.6 0.9 0.7 0.8 0.5 1. 0.3\n", + " 0.4 0.7 0.5 0.3 1. 0.3 0.1 0.6 0.2 0. 0.2 0.8 0.7 0.7\n", + " 0.6 0.4 0.7 0.7 0.5 0.1 0.9 0. 0.1 0.3 0.3 0.1 0.6 0.5\n", + " 0.4 0.1 0.3 0.2 0.1 0.7 0.3 0.8 0.8 0.9 0.7 0.5 0. 0.9\n", + " 0.5 0.6 1. 0.9 0.8 0. 0.7 0.3 0.4 0.2 0.3 0.4 0.9 0.4 1.\n", + " 0.2]\n", + " [ 1. 0.1 0.8 0. 0.4 0.2 0.2 0.8 0.1 0.2 0.1 0.9 0.9 0.9\n", + " 0.5 0.7 0.8 0.6 0.1 0.2 0.2 0.5 0.4 0.6 1. 0.1 0.8 0.5\n", + " 0.3 0.6 0.6 1. 0.5 0.4 0.3 0.8 0.7 0.4 0.1 1. 0.6 0.3\n", + " 0.7 0.4 0.5 1. 0.6 0.8 0.5 0.6 1. 0.7 0.2 0.6 0.4 0. 0.8\n", + " 0.5 0.5 0.2 0.8 0.2 0.4 0.5 0.2 0. 0.8 0.4 0.4 0.4 0.4\n", + " 0.4 0.8 0.4 0.1 0.9 0.1 0.8 0.2 0.7 1. 0.3 0.1 0.9 0.3\n", + " 0.1 0.1 0.4 0.5 0.5 0.6 0.2 0.2 0.4 0.5 0.6 0.3 0.2 0.6\n", + " 0.7]\n", + " [ 0.1 0.5 0.4 0.1 0.1 0.9 0.5 0.9 0.8 0.8 0.8 0.4 0.4 0.7 0.\n", + " 0.4 0. 0.4 0.7 0.7 0.7 0.8 0.9 0. 0.6 0.8 1. 0.5 0. 0.9\n", + " 0.9 1. 0.6 0.4 0.4 0.8 0.9 0.2 0.1 0.2 0.7 0.8 0.2 0.1\n", + " 0.9 0.9 0.4 0.6 0.7 0.4 0.6 0.2 0.9 0.9 0.3 0.7 0.6 0.2\n", + " 0.3 0.8 0.6 0.6 0.1 0.3 0.2 0.6 0.3 0.7 0.4 0.5 0.3 0.4\n", + " 0.4 0.9 0.6 0.6 0.3 0.1 0.3 0.8 0.3 0.7 0.4 0.5 0.4 0.7\n", + " 0.6 0.1 0.8 0.2 0.6 0.1 1. 0.8 0.2 0.6 0.9 0.2 0.4 0.4]\n", + " [ 0.4 0.5 0.5 0.7 0.3 0.7 0.2 0.3 0.6 0.9 0.7 0.3 0.1 0.4\n", + " 0.6 0.8 0.3 0.2 0.4 0.2 0.8 0.4 0.2 0.9 0.2 0.9 0.8 0.5\n", + " 0.9 0.7 0.2 0.5 0.3 0.7 0.6 0. 0.3 0.5 0.6 0.8 0.5 0.9\n", + " 0.2 0.1 0.3 0.9 0.3 0.3 0.6 0.5 0.3 1. 0.2 0.9 0.7 0.9\n", + " 0.2 0.1 0.1 0.4 0.1 0.7 0.4 0.2 0.3 0.4 0.7 1. 0.9 0.5\n", + " 0.1 0.9 0.5 0.1 0.4 0.9 0.7 0.3 0.5 0.3 0.3 1. 0.7 0.8\n", + " 0.3 0.6 0.3 0.6 0.7 0.7 0. 0.7 0.6 0.1 0.9 1. 0.1 0.1\n", + " 0.2 0.7]\n", + " [ 0.1 0.1 0.4 0.6 1. 0.4 0.1 0.4 0.5 0. 0.3 0.3 0.7 0.4\n", + " 0.7 0.8 0. 0.8 0.1 0.9 0.7 0.9 0.9 0.6 0.2 0.2 0.4 0.5\n", + " 0.3 0.1 0.6 0.8 0.9 0.5 0.4 0.4 0.6 0.3 0.5 0.4 0.7 0.2\n", + " 0.4 0.3 0.6 0.8 0.8 1. 0.5 0.7 0.6 1. 0.5 0.1 0.2 0.1\n", + " 0.4 0.3 0.5 0.3 0.5 0.6 0.2 0.3 0.8 0.5 0.6 0.9 0.8 0.3\n", + " 0.3 0.5 0.2 0.1 0.5 0.4 0.4 0.6 0.2 0.5 0.8 0.2 0.4 0.6\n", + " 0.2 0.3 0.4 0.8 0.3 0.2 0.6 0.5 0.4 0.3 0.4 0.6 0.1 0.6\n", + " 0.9 0.9]\n", + " [ 0.6 0.6 0.1 0.4 0.6 0.8 0. 0.5 0.9 0.4 0.6 0.5 0.5 0.7\n", + " 0.9 0.7 0.1 0.4 0.3 0.5 0.3 0.5 0.3 1. 0.4 0.5 0.1 0.4\n", + " 0.3 0.6 0.6 0.3 0.4 0.8 0.5 0.4 0. 0. 0.8 0.7 0.9 0.5\n", + " 0.2 0.2 0.1 0.3 0.2 0.6 0.7 0.2 0.9 0.2 0.3 0.5 0.4 0.2\n", + " 0.9 0.8 0.1 0.2 0.8 0.3 0.9 0.6 0.3 0. 0.6 0. 0.1 0.7\n", + " 0.7 0.2 0.8 0.4 0.4 0.6 0.2 0.3 0.4 0.5 0.9 0.3 0. 0.6\n", + " 0.4 0.9 0.6 0.3 1. 0.9 0.6 0.9 0. 0.5 0.2 0.4 1. 0.5\n", + " 0.7 0.9]\n", + " [ 0.3 0.2 0.9 0.4 0.8 0.8 1. 0.1 0.8 0.1 0.1 0.7 0.5 0.6\n", + " 0.1 0.5 0.5 0.4 0.2 0.8 0. 0.4 0.2 0.1 0.4 1. 0.1 0. 0.7\n", + " 0.1 0.4 0.3 0.7 0.4 0.5 0.5 0. 0.2 0.2 0.9 0.9 0.8 0.1\n", + " 0.3 0.3 0. 0.7 0. 0.8 0.5 0.5 0.3 0.3 0.1 1. 0. 0.9\n", + " 0.8 0.6 0.9 0.5 1. 0.5 0. 0. 0.1 0.6 0.7 0.1 0.6 0.4\n", + " 0.5 0.2 0.4 0.5 0.8 0.6 0.3 1. 0.9 0.6 0.1 0.7 0. 0.7\n", + " 0.4 0.6 0.3 0.5 0.9 0.4 0.8 0.8 0.2 0.3 0.5 0.1 0.5 0.6\n", + " 0.8]\n", + " [ 0.4 0.6 0.6 1. 0.3 0.6 0.6 0.1 0.1 0.9 0.1 0.9 0.5 1. 0.6\n", + " 0.1 0.8 0.1 0.4 0.1 0.7 0.9 0.7 0.4 0.3 0.5 0.5 0.4 0. 0.7\n", + " 0.7 0.3 0.9 1. 0.7 0. 0.2 1. 0.6 0.3 0.3 0.1 0.7 0.5\n", + " 0.3 0.7 0.1 0.9 0.6 0.9 0.3 0.1 0.9 1. 0.1 1. 0.6 0.7\n", + " 0.5 0.6 1. 0.9 0.2 0.2 0.3 0.4 0.6 0.1 0.4 0. 0.9 0.4\n", + " 0.9 0.7 0.1 1. 0.7 0.1 0.7 0.2 0.9 0.7 0.1 0.1 0.9 0.6\n", + " 0.1 0.1 0.2 0.6 0.8 0.9 0.2 0.1 0.2 0.3 0.5 0.7 0.8 0.8]]\n" + ] + } + ], + "source": [ + "x = np.random.uniform(size=[10,100])\n", + "np.set_printoptions(...)\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Base-n representations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Convert 12 into a binary number in string format." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1100\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Convert 12 into a hexadecimal number in string format." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'44C'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [conda root]", + "language": "python", + "name": "conda-root-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/5_Input_and_Output_Solutions.ipynb b/5_Input_and_Output_Solutions.ipynb new file mode 100644 index 0000000..0e6119c --- /dev/null +++ b/5_Input_and_Output_Solutions.ipynb @@ -0,0 +1,524 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Input and Output" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = \"kyubyong. https://github.com/Kyubyong/numpy_exercises\"" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.12.0'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2017-04-01\n" + ] + } + ], + "source": [ + "from datetime import date\n", + "print(date.today())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## NumPy binary files (NPY, NPZ)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Save x into `temp.npy` and load it." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n", + "np.save('temp.npy', x) # Actually you can omit the extension. If so, it will be added automatically.\n", + "\n", + "# Check if there exists the 'temp.npy' file.\n", + "import os\n", + "if os.path.exists('temp.npy'):\n", + " x2 = np.load('temp.npy')\n", + " print(np.array_equal(x, x2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Save x and y into a single file 'temp.npz' and load it." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n", + "y = np.arange(11, 20)\n", + "np.savez('temp.npz', x=x, y=y)\n", + "# np.savez_compressed('temp.npz', x=x, y=y) # If you want to save x and y into a single file in compressed .npz format.\n", + "with np.load('temp.npz') as data:\n", + " x2 = data['x']\n", + " y2 = data['y']\n", + " print(np.array_equal(x, x2))\n", + " print(np.array_equal(y, y2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Text files" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Save x to 'temp.txt' in string format and load it." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 1., 2., 3., 4.],\n", + " [ 5., 6., 7., 8., 9.]])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(10).reshape(2, 5)\n", + "header = 'num1 num2 num3 num4 num5'\n", + "np.savetxt('temp.txt', x, fmt=\"%d\", header=header) \n", + "np.loadtxt('temp.txt')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Save `x`, `y`, and `z` to 'temp.txt' in string format line by line, then load it." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],\n", + " [ 11., 12., 13., 14., 15., 16., 17., 18., 19., 20.],\n", + " [ 22., 23., 24., 25., 26., 27., 28., 29., 30., 31.]])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x = np.arange(10)\n", + "y = np.arange(11, 21)\n", + "z = np.arange(22, 32)\n", + "np.savetxt('temp.txt', (x, y, z), fmt='%d')\n", + "np.loadtxt('temp.txt')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Convert `x` into bytes, and load it as array." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3, 4])\n", + "x_bytes = x.tostring() # Don't be misled by the function name. What it really does is it returns bytes.\n", + "x2 = np.fromstring(x_bytes, dtype=x.dtype) # returns a 1-D array even if x is not.\n", + "print(np.array_equal(x, x2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Convert `a` into an ndarray and then convert it into a list again." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "a = [[1, 2], [3, 4]]\n", + "x = np.array(a)\n", + "a2 = x.tolist()\n", + "print(a == a2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## String formatting¶" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Convert `x` to a string, and revert it." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]] \n", + " \n" + ] + } + ], + "source": [ + "x = np.arange(10).reshape(2,5)\n", + "x_str = np.array_str(x)\n", + "print(x_str, \"\\n\", type(x_str))\n", + "x_str = x_str.replace(\"[\", \"\") # [] must be stripped\n", + "x_str = x_str.replace(\"]\", \"\")\n", + "x2 = np.fromstring(x_str, dtype=x.dtype, sep=\" \").reshape(x.shape)\n", + "assert np.array_equal(x, x2)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Text formatting options" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Print `x` such that all elements are displayed with precision=1, no suppress." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.5 0. 0.8 0.2 0.3 0.2 0.2 1. 0.4 0.8 0.6 0.2 0.5 0.1\n", + " 0.4 0.1 0.9 0.6 0.1 0.5 0.8 0.8 0.8 0. 0.6 0.8 0.4 0.3\n", + " 0.8 0.2 0.7 0.7 0.2 1. 0.8 0.1 0.2 0.1 0.3 0.1 0.5 0.9\n", + " 0.6 0.9 0.6 0.5 0.8 0.3 0.3 0.5 0.1 0.6 0.1 0.3 0.6 0.2\n", + " 0.4 0.8 0.6 0.4 0.2 0.6 0. 0.3 0.8 0.5 0.7 0.9 0.8 0.6\n", + " 0.9 0.8 0.4 0.4 0.7 0.8 0. 0.1 0.5 0.4 0.7 1. 0.1 0.2\n", + " 0.6 0.3 0.9 0.1 0.6 0.4 0.3 0.8 0.3 0.6 0.6 0.3 1. 0.2\n", + " 0.9 0.2]\n", + " [ 0.9 0.2 0.4 0.9 0.5 0.6 0.1 0.7 0. 0. 0.1 0.8 0.8 1. 0.2\n", + " 0.8 0.3 0.2 1. 0.6 1. 0.3 0.4 0.4 0.7 0.5 0.4 0.8 0.5\n", + " 0.9 0.3 0.5 0.7 0.4 0.2 0.3 0.9 0. 0.6 0.8 0.3 0.5 0.2\n", + " 0.3 0. 0.6 0.5 0.2 0.5 0.8 0.2 0.8 0. 0.9 0. 0.7 0.1\n", + " 0.4 0.2 0.5 0.6 0.2 0.6 0.1 0.1 0. 0.5 0.9 0.4 0.5 0.8\n", + " 0.5 0.1 0.7 0. 1. 0.5 0.4 0.2 0. 1. 0.4 0.1 0.7 0.7\n", + " 0.4 0.8 0.4 0.6 0.6 0.5 0.8 0.8 0.2 0.2 0.3 0.2 0.5 0.9\n", + " 0.5]\n", + " [ 0.3 0.6 0.4 0.5 0.5 0. 0.7 0.1 0. 0.9 0.5 0.7 0.6 0.3\n", + " 0.9 0.5 0.1 0.4 0.1 0.9 0.8 0.6 0.8 0.8 0.1 0.4 0.9 0.1 1.\n", + " 0.7 0.4 0.3 0.8 0.3 0.8 0.8 0.2 0.7 0.2 0.8 0.3 0.9 0.1\n", + " 0.9 0.2 0.8 0.9 0.6 0.1 0.3 0.4 1. 0.1 0.7 0.3 0.9 0.3\n", + " 0.5 0.9 0. 0.6 0. 0.8 0.1 0.9 0. 0.8 0.6 0.5 0.5 0.2 1.\n", + " 0.4 0. 0.2 0. 0.9 0.9 0.8 0.2 0.7 0.3 0.2 0.1 1. 0.4\n", + " 0.5 0.4 0.8 0.8 0.8 0.7 0.6 0.4 0.7 0.6 0.5 0.8 0.7 0.6]\n", + " [ 0.2 0.6 0.9 0.7 0.1 0.1 1. 0.5 0.8 0.3 1. 0.4 0.1 0.5\n", + " 0.6 0.8 0.8 0.8 0.1 1. 0.8 0. 0.7 0.6 0.8 0.2 0.5 0.9\n", + " 0.4 0.8 0.7 0.2 0.8 0.6 0.9 0.6 0.9 0.8 0.9 1. 0.6 0.6\n", + " 0.7 0.1 0.5 0.3 0. 0.8 0. 0.5 0.8 0.3 0.8 0.7 0.1 0.5\n", + " 0.2 0.1 0.7 0. 0. 0.6 0. 0.8 0.7 0.1 0.4 0.1 0.2 0.1\n", + " 0.9 0.6 0.9 0.3 0.4 0.9 0.2 0.6 0.8 0.9 0.6 0.8 0.5 0.1\n", + " 0.6 1. 0. 0.7 0.7 0.4 0.1 0.9 0.4 0.1 0.7 0.6 0.3 0.9\n", + " 0.3 0.5]\n", + " [ 0.9 0.3 0.1 0.1 0.2 0.4 0.3 0.5 0.2 0. 0.5 0.4 0.5 0.3\n", + " 0.6 1. 0.1 0.7 0.6 0.2 0.3 0.3 0.1 0.5 0.6 0. 0.6 0.7\n", + " 0.6 0.4 0.2 0.6 0.1 0.9 0.9 0.1 0.9 0.1 0.6 0.6 0. 0.1\n", + " 0.6 0.4 0.3 0.1 0.9 0.8 0.1 0.2 0.8 0.4 0.7 0.8 0.6 0.4\n", + " 0.9 0.3 0.6 0.7 0.4 0.8 0.3 0. 0. 0.9 0.3 0.3 0.8 0.5\n", + " 0.8 1. 0.2 0.6 0.6 0.2 0.2 0.2 0.4 0.6 0.6 0.4 0.4 0.8\n", + " 0.2 0.5 0.7 0.7 0.1 0.9 0.5 0.6 0.3 0.3 0.6 0.8 0.6 0.8\n", + " 0.4 0.3]\n", + " [ 0.3 1. 0.6 0.9 0.6 1. 0.7 0.9 0.4 0.3 0.9 0.9 0.3 0.8\n", + " 0.3 0.6 0.7 0.3 0.1 0.1 0.4 0.3 0.6 0.5 0.1 0.6 0.1 0.5\n", + " 0.9 0.5 0.5 0.6 0.4 0.4 0.3 1. 0.6 0.6 0.3 0.1 0.4 0.7\n", + " 0.7 0.1 0.5 0.1 0.3 0.1 0.6 0.7 0. 0.1 0.2 0.4 0.1 0.4\n", + " 0.7 0.3 0.2 0.9 0.5 0. 0.4 0.9 1. 0.4 0. 0.2 0.3 0.9\n", + " 0.3 0. 0.8 0.9 0.8 0.6 0.4 0.5 0. 0.9 0.6 0.6 0.1 0.6\n", + " 0.9 0.1 0.8 0.6 0.6 0.5 0.7 1. 0.5 0.3 0.3 0.4 0.6 0.6 1.\n", + " 0.2]\n", + " [ 0.7 0.7 0.9 0.2 0.6 0.3 0.9 0.2 0.9 0.8 0.5 0.3 0.9 0.5 1.\n", + " 0.6 0.9 0.5 0.5 0.1 0.8 0.3 0.9 0.5 0.7 1. 0.6 0.7 0.1\n", + " 0.7 0.9 0.4 0.8 0.9 0.4 1. 0.1 1. 0.5 0.1 0.4 0.7 1. 0.4\n", + " 0.3 0.2 0.2 0.6 0.6 0.3 0.7 0.5 0.7 0.1 0.3 0.5 1. 0.8\n", + " 0.4 0.8 0.8 0.7 0.1 0.2 0.4 0.3 0.4 0.3 0.5 0.4 0.6 0.3\n", + " 0.1 0.7 0.8 0.6 0.6 0.2 0.7 0.9 0.9 0.7 0.3 0.9 0.4 0.6 0.\n", + " 0.4 0.4 0.2 0.8 0.3 0.1 0.2 0.6 0.5 0.9 0.8 0.9 0.7]\n", + " [ 0.8 0.7 0.7 0.6 0.9 0.1 0.4 0.9 1. 0.3 0. 0.2 0.1 0.5\n", + " 0.8 0.1 0.7 0.7 0.6 1. 0.7 1. 0.4 0.6 0.2 0.4 0.4 0.6 0.\n", + " 0.1 1. 0.5 0.1 0.2 0.8 0.2 0.1 0.4 0.7 0.5 0.4 1. 0.5\n", + " 0.5 0.4 0.8 0.2 0.1 0.7 0.2 0.1 0.4 0.3 0.6 0.9 0.9 0.9\n", + " 0.9 0.1 0.1 0. 1. 0. 0.1 0.4 0.6 1. 0.4 0.9 0.3 0.2\n", + " 0.7 0. 0.3 0.2 0.7 0.4 0.3 0.9 0.3 0. 0.5 0.2 0.3 0.1\n", + " 0.2 0. 0.1 0.6 0.9 0.2 0.5 0.8 0.7 0. 0.4 0.8 0.8 0.5\n", + " 0.2]\n", + " [ 0.2 0.3 0. 0.1 0.8 0.4 0.1 0.2 0. 0.7 0. 1. 0.6 0.7\n", + " 0.3 0.3 0.7 0.9 0.3 0.7 0.1 0.1 0.5 0.6 0.3 0.8 0.7 0.1\n", + " 0.6 0.6 0.3 0.2 0.3 0.3 1. 0.1 0.1 0.2 0.4 0.4 0.6 0.5\n", + " 0.7 0.7 0.2 0. 0.8 0.3 0.9 0.1 0.1 0.4 0.4 0.5 0.3 0.9\n", + " 0.6 0.9 0.3 0.5 0. 0.4 0.8 1. 0.3 0.5 0.7 0.5 0.8 0.7\n", + " 0.6 0.3 0.1 0.2 0.5 1. 0.9 0.5 0.6 0.6 0.2 0.8 0.6 0. 0.5\n", + " 0.6 0.8 0.5 0.8 0.8 0.9 0.7 0.9 0.5 0.2 1. 1. 0.1 0.3\n", + " 0.3]\n", + " [ 0. 0.3 0.4 0.7 0.2 0.9 0.2 0.3 0.6 0.8 0.4 0.7 0.3 0.5\n", + " 0.6 0.3 0.7 0. 0.1 0.1 0.9 0. 0.7 0.7 0.1 0.6 0.6 0. 0.3\n", + " 0.5 0.9 0.3 0.1 0.3 0.1 0.9 0.6 0.3 0.3 0.4 0.4 0.2 0.3\n", + " 0.1 0.5 0.3 0.8 0. 0.8 0.6 0.2 0.7 0.4 0.8 0.2 0.9 1. 1.\n", + " 0.7 0.9 0.1 0.2 0. 0.5 0.8 0.7 0.6 0.7 0.7 0.5 0.9 0.2\n", + " 0.2 0.1 0.2 0.1 0.7 1. 0.6 0.3 0.9 1. 0.3 0.3 0.7 0.9\n", + " 0.5 0.8 0.9 0.7 0.2 0.7 0.3 0.1 0.9 0.2 0.5 0.6 0.3 0.4]]\n" + ] + } + ], + "source": [ + "x = np.random.uniform(size=[10,100])\n", + "np.set_printoptions(precision=1, threshold=np.nan, suppress=True)\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Base-n representations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Convert 12 into a binary number in string format." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1100\n" + ] + } + ], + "source": [ + "out1 = np.binary_repr(12)\n", + "out2 = np.base_repr(12, base=2)\n", + "assert out1 == out2 # But out1 is better because it's much faster.\n", + "print(out1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Convert 12 into a hexadecimal number in string format." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'44C'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.base_repr(1100, base=16)" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [conda root]", + "language": "python", + "name": "conda-root-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/6_Linear_algebra.ipynb b/6_Linear_algebra.ipynb new file mode 100644 index 0000000..c86d6c8 --- /dev/null +++ b/6_Linear_algebra.ipynb @@ -0,0 +1,509 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Linear algebra" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Matrix and vector products" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = [1,2]\n", + "y = [[4, 1], [2, 2]]\n", + "#print np.dot(x, y)\n", + "#print np.dot(y, x)\n", + "#print np.matmul(x, y)\n", + "#print np.inner(x, y)\n", + "#print np.inner(y, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = [[1, 0], [0, 1]]\n", + "y = [[4, 1], [2, 2], [1, 1]]\n", + "#print np.dot(y, x)\n", + "#print np.matmul(y, x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([[1, 4], [5, 6]])\n", + "y = np.array([[4, 1], [2, 2]])\n", + "#print np.vdot(x, y)\n", + "#print np.vdot(y, x)\n", + "#print np.dot(x.flatten(), y.flatten())\n", + "#print np.inner(x.flatten(), y.flatten())\n", + "#print (x*y).sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array(['a', 'b'], dtype=object)\n", + "y = np.array([1, 2])\n", + "#print np.inner(x, y)\n", + "#print np.inner(y, x)\n", + "#print np.outer(x, y)\n", + "#print np.outer(y, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Decompositions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Get the lower-trianglular `L` in the Cholesky decomposition of x and verify it." + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 2. 0. 0.]\n", + " [ 6. 1. 0.]\n", + " [-8. 5. 3.]]\n" + ] + } + ], + "source": [ + "x = np.array([[4, 12, -16], [12, 37, -43], [-16, -43, 98]], dtype=np.int32)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Compute the qr factorization of x and verify it." + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q=\n", + "[[-0.85714287 0.39428571 0.33142856]\n", + " [-0.42857143 -0.90285712 -0.03428571]\n", + " [ 0.2857143 -0.17142858 0.94285715]] \n", + "r=\n", + "[[ -14. -21. 14.]\n", + " [ 0. -175. 70.]\n", + " [ 0. 0. -35.]]\n" + ] + } + ], + "source": [ + "x = np.array([[12, -51, 4], [6, 167, -68], [-4, 24, -41]], dtype=np.float32)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Factor x by Singular Value Decomposition and verify it." + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "U=\n", + "[[ 0. 1. 0. 0.]\n", + " [ 1. 0. 0. 0.]\n", + " [ 0. 0. 0. -1.]\n", + " [ 0. 0. 1. 0.]] \n", + "s=\n", + "[ 3. 2.23606801 2. 0. ] \n", + "V=\n", + "[[ 1. 0. 0.]\n", + " [ 0. 1. 0.]\n", + " [ 0. 0. 1.]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 0, 0, 0, 2], [0, 0, 3, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0]], dtype=np.float32)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Matrix eigenvalues" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Compute the eigenvalues and right eigenvectors of x. (Name them eigenvals and eigenvecs, respectively)" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "eigenvalues are\n", + "[ 1. 2. 3.]\n", + "eigenvectors are\n", + "[[ 1. 0. 0.]\n", + " [ 0. 1. 0.]\n", + " [ 0. 0. 1.]]\n" + ] + } + ], + "source": [ + "x = np.diag((1, 2, 3))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.array_equal(np.dot(x, eigenvecs), eigenvals * eigenvecs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Norms and other numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Calculate the Frobenius norm and the condition number of x." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16.8819430161\n", + "4.56177073661e+17\n" + ] + } + ], + "source": [ + "x = np.arange(1, 10).reshape((3, 3))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Calculate the determinant of x." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-2.0\n" + ] + } + ], + "source": [ + "x = np.arange(1, 5).reshape((2, 2))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Calculate the rank of x." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + } + ], + "source": [ + "x = np.eye(4)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Compute the sign and natural logarithm of the determinant of x." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1.0 0.69314718056\n" + ] + } + ], + "source": [ + "x = np.arange(1, 5).reshape((2, 2))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Return the sum along the diagonal of x." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4.0\n" + ] + } + ], + "source": [ + "x = np.eye(4)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solving equations and inverting matrices" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "Q15. Compute the inverse of x." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[-2. 1. ]\n", + " [ 1.5 -0.5]]\n" + ] + } + ], + "source": [ + "x = np.array([[1., 2.], [3., 4.]])\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/6_Linear_algebra_Solutions.ipynb b/6_Linear_algebra_Solutions.ipynb new file mode 100644 index 0000000..3e78a91 --- /dev/null +++ b/6_Linear_algebra_Solutions.ipynb @@ -0,0 +1,602 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Linear algebra" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Matrix and vector products" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[8 5]\n", + "[6 6]\n", + "[8 5]\n", + "[6 6]\n", + "[6 6]\n" + ] + } + ], + "source": [ + "x = [1,2]\n", + "y = [[4, 1], [2, 2]]\n", + "print np.dot(x, y)\n", + "print np.dot(y, x)\n", + "print np.matmul(x, y)\n", + "print np.inner(x, y)\n", + "print np.inner(y, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[4 1]\n", + " [2 2]\n", + " [1 1]]\n", + "[[4 1]\n", + " [2 2]\n", + " [1 1]]\n" + ] + } + ], + "source": [ + "x = [[1, 0], [0, 1]]\n", + "y = [[4, 1], [2, 2], [1, 1]]\n", + "print np.dot(y, x)\n", + "print np.matmul(y, x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "30\n", + "30\n", + "30\n", + "30\n", + "30\n" + ] + } + ], + "source": [ + "x = np.array([[1, 4], [5, 6]])\n", + "y = np.array([[4, 1], [2, 2]])\n", + "print np.vdot(x, y)\n", + "print np.vdot(y, x)\n", + "print np.dot(x.flatten(), y.flatten())\n", + "print np.inner(x.flatten(), y.flatten())\n", + "print (x*y).sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "abb\n", + "abb\n", + "[['a' 'aa']\n", + " ['b' 'bb']]\n", + "[['a' 'b']\n", + " ['aa' 'bb']]\n" + ] + } + ], + "source": [ + "x = np.array(['a', 'b'], dtype=object)\n", + "y = np.array([1, 2])\n", + "print np.inner(x, y)\n", + "print np.inner(y, x)\n", + "print np.outer(x, y)\n", + "print np.outer(y, x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Decompositions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Get the lower-trianglular `L` in the Cholesky decomposition of x and verify it." + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 2. 0. 0.]\n", + " [ 6. 1. 0.]\n", + " [-8. 5. 3.]]\n" + ] + } + ], + "source": [ + "x = np.array([[4, 12, -16], [12, 37, -43], [-16, -43, 98]], dtype=np.int32)\n", + "L = np.linalg.cholesky(x)\n", + "print L\n", + "assert np.array_equal(np.dot(L, L.T.conjugate()), x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Compute the qr factorization of x and verify it." + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q=\n", + "[[-0.85714287 0.39428571 0.33142856]\n", + " [-0.42857143 -0.90285712 -0.03428571]\n", + " [ 0.2857143 -0.17142858 0.94285715]] \n", + "r=\n", + "[[ -14. -21. 14.]\n", + " [ 0. -175. 70.]\n", + " [ 0. 0. -35.]]\n" + ] + } + ], + "source": [ + "x = np.array([[12, -51, 4], [6, 167, -68], [-4, 24, -41]], dtype=np.float32)\n", + "q, r = np.linalg.qr(x)\n", + "print \"q=\\n\", q, \"\\nr=\\n\", r\n", + "assert np.allclose(np.dot(q, r), x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Factor x by Singular Value Decomposition and verify it." + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "U=\n", + "[[ 0. 1. 0. 0.]\n", + " [ 1. 0. 0. 0.]\n", + " [ 0. 0. 0. -1.]\n", + " [ 0. 0. 1. 0.]] \n", + "s=\n", + "[ 3. 2.23606801 2. 0. ] \n", + "V=\n", + "[[ 1. 0. 0.]\n", + " [ 0. 1. 0.]\n", + " [ 0. 0. 1.]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 0, 0, 0, 2], [0, 0, 3, 0, 0], [0, 0, 0, 0, 0], [0, 2, 0, 0, 0]], dtype=np.float32)\n", + "U, s, V = np.linalg.svd(x, full_matrices=False)\n", + "print \"U=\\n\", U, \"\\ns=\\n\", s, \"\\nV=\\n\", v\n", + "assert np.allclose(np.dot(U, np.dot(np.diag(s), V)), x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Matrix eigenvalues" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Compute the eigenvalues and right eigenvectors of x. (Name them eigenvals and eigenvecs, respectively)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "eigenvalues are\n", + "[ 1. 2. 3.]\n", + "eigenvectors are\n", + "[[ 1. 0. 0.]\n", + " [ 0. 1. 0.]\n", + " [ 0. 0. 1.]]\n" + ] + } + ], + "source": [ + "x = np.diag((1, 2, 3))\n", + "eigenvals = np.linalg.eig(x)[0]\n", + "eigenvals_ = np.linalg.eigvals(x)\n", + "assert np.array_equal(eigenvals, eigenvals_)\n", + "print \"eigenvalues are\\n\", eigenvals\n", + "eigenvecs = np.linalg.eig(x)[1]\n", + "print \"eigenvectors are\\n\", eigenvecs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Predict the results of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "print np.array_equal(np.dot(x, eigenvecs), eigenvals * eigenvecs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Norms and other numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Calculate the Frobenius norm and the condition number of x." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16.8819430161\n", + "4.56177073661e+17\n" + ] + } + ], + "source": [ + "x = np.arange(1, 10).reshape((3, 3))\n", + "print np.linalg.norm(x, 'fro')\n", + "print np.linalg.cond(x, 'fro')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Calculate the determinant of x." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-2.0\n" + ] + } + ], + "source": [ + "x = np.arange(1, 5).reshape((2, 2))\n", + "out1 = np.linalg.det(x)\n", + "out2 = x[0, 0] * x[1, 1] - x[0, 1] * x[1, 0]\n", + "assert np.allclose(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Calculate the rank of x." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + } + ], + "source": [ + "x = np.eye(4)\n", + "out1 = np.linalg.matrix_rank(x)\n", + "out2 = np.linalg.svd(x)[1].size\n", + "assert out1 == out2\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Compute the sign and natural logarithm of the determinant of x." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1.0 0.69314718056\n" + ] + } + ], + "source": [ + "x = np.arange(1, 5).reshape((2, 2))\n", + "sign, logdet = np.linalg.slogdet(x)\n", + "det = np.linalg.det(x)\n", + "assert sign == np.sign(det)\n", + "assert logdet == np.log(np.abs(det))\n", + "print sign, logdet\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Return the sum along the diagonal of x." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4.0\n" + ] + } + ], + "source": [ + "x = np.eye(4)\n", + "out1 = np.trace(x)\n", + "out2 = x.diagonal().sum()\n", + "assert out1 == out2\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solving equations and inverting matrices" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "Q15. Compute the inverse of x." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[-2. 1. ]\n", + " [ 1.5 -0.5]]\n" + ] + } + ], + "source": [ + "x = np.array([[1., 2.], [3., 4.]])\n", + "out1 = np.linalg.inv(x)\n", + "assert np.allclose(np.dot(x, out1), np.eye(2))\n", + "print out1\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/7_Discrete_Fourier_Transform.ipynb b/7_Discrete_Fourier_Transform.ipynb new file mode 100644 index 0000000..d00546f --- /dev/null +++ b/7_Discrete_Fourier_Transform.ipynb @@ -0,0 +1,408 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.date(2017, 11, 2)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from datetime import date\n", + "date.today()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = \"kyubyong. https://github.com/Kyubyong/numpy_exercises\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.13.1'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Complex Numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Return the angle of `a` in radian." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.785398163397\n" + ] + } + ], + "source": [ + "a = 1+1j\n", + "output = ...\n", + "print(output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Return the real part and imaginary part of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "real part= [ 1. 3. 5.]\n", + "imaginary part= [ 2. 4. 6.]\n" + ] + } + ], + "source": [ + "a = np.array([1+2j, 3+4j, 5+6j])\n", + "real = ...\n", + "imag = ...\n", + "print(\"real part=\", real)\n", + "print(\"imaginary part=\", imag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Replace the real part of a with `9`, the imaginary part with `[5, 7, 9]`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 9.+5.j 9.+7.j 9.+9.j]\n" + ] + } + ], + "source": [ + "a = np.array([1+2j, 3+4j, 5+6j])\n", + "...\n", + "...\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Return the complex conjugate of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1-2j)\n" + ] + } + ], + "source": [ + "a = 1+2j\n", + "output = ...\n", + "print(output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Discrete Fourier Transform" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Compuete the one-dimensional DFT of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 8.00000000e+00 -6.85802208e-15j 2.36524713e-15 +9.79717439e-16j\n", + " 9.79717439e-16 +9.79717439e-16j 4.05812251e-16 +9.79717439e-16j\n", + " 0.00000000e+00 +9.79717439e-16j -4.05812251e-16 +9.79717439e-16j\n", + " -9.79717439e-16 +9.79717439e-16j -2.36524713e-15 +9.79717439e-16j]\n" + ] + } + ], + "source": [ + "a = np.exp(2j * np.pi * np.arange(8))\n", + "output = ...\n", + "print(output)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Compute the one-dimensional inverse DFT of the `output` in the above question." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a= [ 1. +0.00000000e+00j 1. -2.44929360e-16j 1. -4.89858720e-16j\n", + " 1. -7.34788079e-16j 1. -9.79717439e-16j 1. -1.22464680e-15j\n", + " 1. -1.46957616e-15j 1. -1.71450552e-15j]\n", + "inversed= [ 1. +0.00000000e+00j 1. -2.44929360e-16j 1. -4.89858720e-16j\n", + " 1. -7.34788079e-16j 1. -9.79717439e-16j 1. -1.22464680e-15j\n", + " 1. -1.46957616e-15j 1. -1.71450552e-15j]\n" + ] + } + ], + "source": [ + "print(\"a=\", a)\n", + "inversed = ...\n", + "print(\"inversed=\", a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Compute the one-dimensional discrete Fourier Transform for real input `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.+0.j 0.-1.j -1.+0.j]\n", + "[ 1.+0.j 0.-1.j -1.+0.j 0.+1.j]\n" + ] + } + ], + "source": [ + "a = [0, 1, 0, 0]\n", + "output = ...\n", + "print(output)\n", + "assert output.size==len(a)//2+1 if len(a)%2==0 else (len(a)+1)//2\n", + "\n", + "# cf.\n", + "output2 = np.fft.fft(a)\n", + "print(output2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Compute the one-dimensional inverse DFT of the output in the above question." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "inversed= [0, 1, 0, 0]\n" + ] + } + ], + "source": [ + "inversed = ...\n", + "print(\"inversed=\", a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Return the DFT sample frequencies of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0. 0.125 0.25 0.375 -0.5 -0.375 -0.25 -0.125]\n" + ] + } + ], + "source": [ + "signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=np.float32)\n", + "fourier = np.fft.fft(signal)\n", + "n = signal.size\n", + "freq = ...\n", + "print(freq)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Window Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nVSvJQHmzVKBqWWxCUk4Kll2Mt8LeWDaVStgsVC1xxeBayCYsl4SYAFkHNlqSEBszIsYQY8uXyFd8\niYUlyx5JI0saSXPp7nf/OGeulrmIHo1m+vlUner3vOd099v2vK3T3/Oe99Ayi6MWUkqM/tM/MdTf\nz7H+fk7e/wDU65Qvuoi+T36Srre8+fQDluoIDDwGz343C1f2fA/qY9DaBedvy26HdsGboGtlYz/U\nWWzkxNhEmHLwuWMc2DvE4f3HqdcSAKXWAstXV1h/1SrOe80yVl20hFKTfzFJkiTp7NdSLrJuQw/r\nNvSQUmLw+eM8u/sgzz95hL2PD/LEPS9M7FtZWmb56ix86VnTxfLVFbqWtS3suxp1nweb35stYyfh\n2bvzE9B/ly0APb+QhS7nb4dzNp7WTT/KF15I3803s/yGG7JLij77OQ7978/SsmYNlW1b6dq2jY5N\nm4iW2Qu73n5ZH6O1Oh+67R95/627+KNfu4JyqXl/0xi0nAX+ctdePvy13fyzi3r49Lsvp3UWrm9M\nY2Oc2HV/Fq7s7Gdsz48AKF98Mcv/7b+hsm0bbZdc8rMFLKMnskuB9j8I+x/KloHHsmAFoOdiuPL9\nWVJ77pWzdr/5s0VKiWODw9NClYN7hzh2aHhin45FrSxfU+G8S5ZN/COzqKf9jM/DI0mSJDVSRLCs\nr8KyvgpXXJPVnTg6Om0E98HnjrFn90FSdr6R1vZSPuKlMjECpntl58Kc76WlHS58U7akj8Ohp/PQ\n5Xa454/he/8z22/Judno/3M2ZMHLORug0vtTvUX5ggvou/kP6P0vH2KofydD/f289JWvcviLf0ah\nUqFzy1V0bd9OZcuWWZlA952b1lCtJX7r67u58c8f4A/fffmsDiA4mxm0zLEdDz3Pf77tId54/nL+\nuMGpX+3IEYbu+i5D/f0M3XUX9aNHiZYWOq68kqXXX0/X1q20rFr1073Y8FF4YfdkoLL/ITj4BKR6\ntr19KazaCG+4Mfsy6NsES9Y07LOcTVJKnDw2xtDh4ezyn+eGJv4BGTlRzXaKbFjlinWLuGTLKnrW\ndLFsdaW5rleVJElSU+tY1Mq567ObOIwbG61xaN/QtPDl0e8+T3U0+11RKAZLV3VmAczq7Bh60bI2\nOpeUF04AEwHLL8iW198AI0Ow9wew/x8nf2s99v8m9+86Z0r4ki+L+l5xgt2WFSvovu5auq+7lvqJ\n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\nf9alElAadvRbAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure(figsize=(19, 10))\n", + "\n", + "# Hamming window\n", + "window = np.hamming(51)\n", + "plt.plot(np.bartlett(51), label=\"Bartlett window\")\n", + "plt.plot(np.blackman(51), label=\"Blackman window\")\n", + "plt.plot(np.hamming(51), label=\"Hamming window\")\n", + "plt.plot(np.hanning(51), label=\"Hanning window\")\n", + "plt.plot(np.kaiser(51, 14), label=\"Kaiser window\")\n", + "plt.xlabel(\"sample\")\n", + "plt.ylabel(\"amplitude\")\n", + "plt.legend()\n", + "plt.grid()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/7_Discrete_Fourier_Transform_solutions.ipynb b/7_Discrete_Fourier_Transform_solutions.ipynb new file mode 100644 index 0000000..4d2b70d --- /dev/null +++ b/7_Discrete_Fourier_Transform_solutions.ipynb @@ -0,0 +1,408 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.date(2017, 11, 2)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from datetime import date\n", + "date.today()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "author = \"kyubyong. https://github.com/Kyubyong/numpy_exercises\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.13.1'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Complex Numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Return the angle of `a` in radian." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.785398163397\n" + ] + } + ], + "source": [ + "a = 1+1j\n", + "output = np.angle(a, deg=False)\n", + "print(output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Return the real part and imaginary part of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "real part= [ 1. 3. 5.]\n", + "imaginary part= [ 2. 4. 6.]\n" + ] + } + ], + "source": [ + "a = np.array([1+2j, 3+4j, 5+6j])\n", + "real = a.real\n", + "imag = a.imag\n", + "print(\"real part=\", real)\n", + "print(\"imaginary part=\", imag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Replace the real part of a with `9`, the imaginary part with `[5, 7, 9]`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 9.+5.j 9.+7.j 9.+9.j]\n" + ] + } + ], + "source": [ + "a = np.array([1+2j, 3+4j, 5+6j])\n", + "a.real = 9\n", + "a.imag = [5, 7, 9]\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Return the complex conjugate of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1-2j)\n" + ] + } + ], + "source": [ + "a = 1+2j\n", + "output = np.conjugate(a)\n", + "print(output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Discrete Fourier Transform" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Compuete the one-dimensional DFT of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 8.00000000e+00 -6.85802208e-15j 2.36524713e-15 +9.79717439e-16j\n", + " 9.79717439e-16 +9.79717439e-16j 4.05812251e-16 +9.79717439e-16j\n", + " 0.00000000e+00 +9.79717439e-16j -4.05812251e-16 +9.79717439e-16j\n", + " -9.79717439e-16 +9.79717439e-16j -2.36524713e-15 +9.79717439e-16j]\n" + ] + } + ], + "source": [ + "a = np.exp(2j * np.pi * np.arange(8))\n", + "output = np.fft.fft(a)\n", + "print(output)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Compute the one-dimensional inverse DFT of the `output` in the above question." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a= [ 1. +0.00000000e+00j 1. -2.44929360e-16j 1. -4.89858720e-16j\n", + " 1. -7.34788079e-16j 1. -9.79717439e-16j 1. -1.22464680e-15j\n", + " 1. -1.46957616e-15j 1. -1.71450552e-15j]\n", + "inversed= [ 1. +0.00000000e+00j 1. -2.44929360e-16j 1. -4.89858720e-16j\n", + " 1. -7.34788079e-16j 1. -9.79717439e-16j 1. -1.22464680e-15j\n", + " 1. -1.46957616e-15j 1. -1.71450552e-15j]\n" + ] + } + ], + "source": [ + "print(\"a=\", a)\n", + "inversed = np.fft.ifft(output)\n", + "print(\"inversed=\", a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Compute the one-dimensional discrete Fourier Transform for real input `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.+0.j 0.-1.j -1.+0.j]\n", + "[ 1.+0.j 0.-1.j -1.+0.j 0.+1.j]\n" + ] + } + ], + "source": [ + "a = [0, 1, 0, 0]\n", + "output = np.fft.rfft(a)\n", + "print(output)\n", + "assert output.size==len(a)//2+1 if len(a)%2==0 else (len(a)+1)//2\n", + "\n", + "# cf.\n", + "output2 = np.fft.fft(a)\n", + "print(output2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Compute the one-dimensional inverse DFT of the output in the above question." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "inversed= [0, 1, 0, 0]\n" + ] + } + ], + "source": [ + "inversed = np.fft.ifft(output)\n", + "print(\"inversed=\", a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Return the DFT sample frequencies of `a`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0. 0.125 0.25 0.375 -0.5 -0.375 -0.25 -0.125]\n" + ] + } + ], + "source": [ + "signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=np.float32)\n", + "fourier = np.fft.fft(signal)\n", + "n = signal.size\n", + "freq = np.fft.fftfreq(n, d=1)\n", + "print(freq)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Window Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nVSvJQHmzVKBqWWxCUk4Kll2Mt8LeWDaVStgsVC1xxeBayCYsl4SYAFkHNlqSEBszIsYQY8uXyFd8\niYUlyx5JI0saSXPp7nf/OGeulrmIHo1m+vlUner3vOd099v2vK3T3/Oe99Ayi6MWUkqM/tM/MdTf\nz7H+fk7e/wDU65Qvuoi+T36Srre8+fQDluoIDDwGz343C1f2fA/qY9DaBedvy26HdsGboGtlYz/U\nWWzkxNhEmHLwuWMc2DvE4f3HqdcSAKXWAstXV1h/1SrOe80yVl20hFKTfzFJkiTp7NdSLrJuQw/r\nNvSQUmLw+eM8u/sgzz95hL2PD/LEPS9M7FtZWmb56ix86VnTxfLVFbqWtS3suxp1nweb35stYyfh\n2bvzE9B/ly0APb+QhS7nb4dzNp7WTT/KF15I3803s/yGG7JLij77OQ7978/SsmYNlW1b6dq2jY5N\nm4iW2Qu73n5ZH6O1Oh+67R95/627+KNfu4JyqXl/0xi0nAX+ctdePvy13fyzi3r49Lsvp3UWrm9M\nY2Oc2HV/Fq7s7Gdsz48AKF98Mcv/7b+hsm0bbZdc8rMFLKMnskuB9j8I+x/KloHHsmAFoOdiuPL9\nWVJ77pWzdr/5s0VKiWODw9NClYN7hzh2aHhin45FrSxfU+G8S5ZN/COzqKf9jM/DI0mSJDVSRLCs\nr8KyvgpXXJPVnTg6Om0E98HnjrFn90FSdr6R1vZSPuKlMjECpntl58Kc76WlHS58U7akj8Ohp/PQ\n5Xa454/he/8z22/Judno/3M2ZMHLORug0vtTvUX5ggvou/kP6P0vH2KofydD/f289JWvcviLf0ah\nUqFzy1V0bd9OZcuWWZlA952b1lCtJX7r67u58c8f4A/fffmsDiA4mxm0zLEdDz3Pf77tId54/nL+\nuMGpX+3IEYbu+i5D/f0M3XUX9aNHiZYWOq68kqXXX0/X1q20rFr1073Y8FF4YfdkoLL/ITj4BKR6\ntr19KazaCG+4Mfsy6NsES9Y07LOcTVJKnDw2xtDh4ezyn+eGJv4BGTlRzXaKbFjlinWLuGTLKnrW\ndLFsdaW5rleVJElSU+tY1Mq567ObOIwbG61xaN/QtPDl0e8+T3U0+11RKAZLV3VmAczq7Bh60bI2\nOpeUF04AEwHLL8iW198AI0Ow9wew/x8nf2s99v8m9+86Z0r4ki+L+l5xgt2WFSvovu5auq+7lvqJ\n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\nf9alElAadvRbAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure(figsize=(19, 10))\n", + "\n", + "# Hamming window\n", + "window = np.hamming(51)\n", + "plt.plot(np.bartlett(51), label=\"Bartlett window\")\n", + "plt.plot(np.blackman(51), label=\"Blackman window\")\n", + "plt.plot(np.hamming(51), label=\"Hamming window\")\n", + "plt.plot(np.hanning(51), label=\"Hanning window\")\n", + "plt.plot(np.kaiser(51, 14), label=\"Kaiser window\")\n", + "plt.xlabel(\"sample\")\n", + "plt.ylabel(\"amplitude\")\n", + "plt.legend()\n", + "plt.grid()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/8_Logic_functions.ipynb b/8_Logic_functions.ipynb new file mode 100644 index 0000000..aac97d8 --- /dev/null +++ b/8_Logic_functions.ipynb @@ -0,0 +1,379 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logic functions" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Truth value testing\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Let x be an arbitrary array. Return True if none of the elements of x is zero. Remind that 0 evaluates to False in python.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n" + ] + } + ], + "source": [ + "x = np.array([1,2,3])\n", + "#\n", + "\n", + "x = np.array([1,0,3])\n", + "#" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Let x be an arbitrary array. Return True if any of the elements of x is non-zero." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n" + ] + } + ], + "source": [ + "x = np.array([1,0,0])\n", + "#\n", + "\n", + "x = np.array([0,0,0])\n", + "#" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Array contents\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1, 0, np.nan, np.inf])\n", + "#print np.isfinite(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1, 0, np.nan, np.inf])\n", + "#print np.isinf(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x = np.array([1, 0, np.nan, np.inf])\n", + "#print np.isnan(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Array type testing" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1+1j, 1+0j, 4.5, 3, 2, 2j])\n", + "#print np.iscomplex(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1+1j, 1+0j, 4.5, 3, 2, 2j])\n", + "#print np.isreal(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.isscalar(3)\n", + "#print np.isscalar([3])\n", + "#print np.isscalar(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Logical operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.logical_and([True, False], [False, False])\n", + "#print np.logical_or([True, False, True], [True, False, False])\n", + "#print np.logical_xor([True, False, True], [True, False, False])\n", + "#print np.logical_not([True, False, 0, 1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.allclose([3], [2.999999])\n", + "#print np.array_equal([3], [2.999999])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Write numpy comparison functions such that they return the results as you see." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True False]\n", + "[ True True]\n", + "[False False]\n", + "[False True]\n" + ] + } + ], + "source": [ + "x = np.array([4, 5])\n", + "y = np.array([2, 5])\n", + "#\n", + "#\n", + "#\n", + "#" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.equal([1, 2], [1, 2.000001])\n", + "#print np.isclose([1, 2], [1, 2.000001])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/8_Logic_functions_Solutions.ipynb b/8_Logic_functions_Solutions.ipynb new file mode 100644 index 0000000..fdd7d85 --- /dev/null +++ b/8_Logic_functions_Solutions.ipynb @@ -0,0 +1,379 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logic functions" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Truth value testing\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Let x be an arbitrary array. Return True if none of the elements of x is zero. Remind that 0 evaluates to False in python.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n" + ] + } + ], + "source": [ + "x = np.array([1,2,3])\n", + "print np.all(x)\n", + "\n", + "x = np.array([1,0,3])\n", + "print np.all(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Let x be an arbitrary array. Return True if any of the elements of x is non-zero." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "False\n" + ] + } + ], + "source": [ + "x = np.array([1,0,0])\n", + "print np.any(x)\n", + "\n", + "x = np.array([0,0,0])\n", + "print np.any(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Array contents\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1, 0, np.nan, np.inf])\n", + "#print np.isfinite(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1, 0, np.nan, np.inf])\n", + "#print np.isinf(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x = np.array([1, 0, np.nan, np.inf])\n", + "#print np.isnan(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Array type testing" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1+1j, 1+0j, 4.5, 3, 2, 2j])\n", + "#print np.iscomplex(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([1+1j, 1+0j, 4.5, 3, 2, 2j])\n", + "#print np.isreal(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.isscalar(3)\n", + "#print np.isscalar([3])\n", + "#print np.isscalar(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Logical operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.logical_and([True, False], [False, False])\n", + "#print np.logical_or([True, False, True], [True, False, False])\n", + "#print np.logical_xor([True, False, True], [True, False, False])\n", + "#print np.logical_not([True, False, 0, 1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.allclose([3], [2.999999])\n", + "#print np.array_equal([3], [2.999999])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Write numpy comparison functions such that they return the results as you see." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True False]\n", + "[ True True]\n", + "[False False]\n", + "[False True]\n" + ] + } + ], + "source": [ + "x = np.array([4, 5])\n", + "y = np.array([2, 5])\n", + "print np.greater(x, y)\n", + "print np.greater_equal(x, y)\n", + "print np.less(x, y)\n", + "print np.less_equal(x, y)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Predict the result of the following code." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "#print np.equal([1, 2], [1, 2.000001])\n", + "#print np.isclose([1, 2], [1, 2.000001])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/9_Mathematical_functions.ipynb b/9_Mathematical_functions.ipynb new file mode 100644 index 0000000..c7f9e71 --- /dev/null +++ b/9_Mathematical_functions.ipynb @@ -0,0 +1,1016 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Mathematical functions" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "__author__ = \"kyubyong. kbpark.linguist@gmail.com. https://github.com/kyubyong\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Trigonometric functions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Calculate sine, cosine, and tangent of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sine: [ 0. 0.84147098 -0.98803162 0.89399666]\n", + "cosine: [ 1. 0.54030231 0.15425145 -0.44807362]\n", + "tangent: [ 0. 1.55740772 -6.4053312 -1.99520041]\n" + ] + } + ], + "source": [ + "x = np.array([0., 1., 30, 90])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Calculate inverse sine, inverse cosine, and inverse tangent of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "inverse sine: [ 1.57079633 0. 1.57079633]\n", + "inverse cosine: [ 0. 1.57079633 0. ]\n", + "inverse tangent: [ 0.78539816 0. 0.78539816]\n" + ] + } + ], + "source": [ + "x = np.array([-1., 0, 1.])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Convert angles from radians to degrees." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-180. -90. 90. 180.]\n" + ] + } + ], + "source": [ + "x = np.array([-np.pi, -np.pi/2, np.pi/2, np.pi])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Convert angles from degrees to radians." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-3.14159265 -1.57079633 1.57079633 3.14159265]\n" + ] + } + ], + "source": [ + "x = np.array([-180., -90., 90., 180.])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Hyperbolic functions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Calculate hyperbolic sine, hyperbolic cosine, and hyperbolic tangent of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1.17520119 0. 1.17520119]\n", + "[ 1.54308063 1. 1.54308063]\n", + "[-0.76159416 0. 0.76159416]\n" + ] + } + ], + "source": [ + "x = np.array([-1., 0, 1.])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rounding" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Predict the results of these, paying attention to the difference among the family functions." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.array([2.1, 1.5, 2.5, 2.9, -2.1, -2.5, -2.9])\n", + "\n", + "out1 = np.around(x)\n", + "out2 = np.floor(x)\n", + "out3 = np.ceil(x)\n", + "out4 = np.trunc(x)\n", + "out5 = [round(elem) for elem in x]\n", + "\n", + "#print out1\n", + "#print out2\n", + "#print out3\n", + "#print out4\n", + "#print out5\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Implement out5 in the above question using numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2. 2. 3. 3. -2. -3. -3.]\n" + ] + } + ], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sums, products, differences" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Predict the results of these." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python2.7/dist-packages/ipykernel/__main__.py:34: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n" + ] + } + ], + "source": [ + "x = np.array(\n", + " [[1, 2, 3, 4],\n", + " [5, 6, 7, 8]])\n", + "\n", + "outs = [np.sum(x),\n", + " np.sum(x, axis=0),\n", + " np.sum(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.prod(x),\n", + " np.prod(x, axis=0),\n", + " np.prod(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.cumsum(x),\n", + " np.cumsum(x, axis=0),\n", + " np.cumsum(x, axis=1),\n", + " \"\",\n", + " np.cumprod(x),\n", + " np.cumprod(x, axis=0),\n", + " np.cumprod(x, axis=1),\n", + " \"\",\n", + " np.min(x),\n", + " np.min(x, axis=0),\n", + " np.min(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.max(x),\n", + " np.max(x, axis=0),\n", + " np.max(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.mean(x),\n", + " np.mean(x, axis=0),\n", + " np.mean(x, axis=1, keepdims=True)]\n", + " \n", + "for out in outs:\n", + " if out == \"\":\n", + " pass\n", + " #print\n", + " else:\n", + " pass\n", + " #print(\"->\", out)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Calculate the difference between neighboring elements, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1 2 3 -7]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 4, 7, 0])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Calculate the difference between neighboring elements, element-wise, and\n", + "prepend [0, 0] and append[100] to it." + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0 0 1 2 3 -7 100]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 4, 7, 0])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Return the cross product of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-3 6 -3]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3])\n", + "y = np.array([4, 5, 6])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exponents and logarithms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Compute $e^x$, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2.71828175 7.38905621 20.08553696]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., 3.], np.float32)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Calculate exp(x) - 1 for all elements in x." + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.71828175 6.38905621 19.08553696]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., 3.], np.float32)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Calculate $2^p$ for all p in x." + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2. 4. 8.]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., 3.], np.float32)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Compute natural, base 10, and base 2 logarithms of x element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "natural log = [ 0. 1. 2.]\n", + "common log = [ 0. 0.43429448 0.86858896]\n", + "base 2 log = [ 0. 1.44269504 2.88539008]\n" + ] + } + ], + "source": [ + "x = np.array([1, np.e, np.e**2])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q16. Compute the natural logarithm of one plus each element in x in floating-point accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.00000000e-099 1.00000000e-100]\n" + ] + } + ], + "source": [ + "x = np.array([1e-99, 1e-100])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Floating point routines" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q17. Return element-wise True where signbit is set." + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True True False False False False]\n" + ] + } + ], + "source": [ + "x = np.array([-3, -2, -1, 0, 1, 2, 3])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q18. Change the sign of x to that of y, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1. -0. -1.]\n" + ] + } + ], + "source": [ + "x = np.array([-1, 0, 1])\n", + "y = -1.1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Arithmetic operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q19. Add x and y element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 0 0]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3])\n", + "y = np.array([-1, -2, -3])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q20. Subtract y from x element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2]\n" + ] + } + ], + "source": [ + "x = np.array([3, 4, 5])\n", + "y = np.array(3)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q21. Multiply x by y element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3 0 -5]\n" + ] + } + ], + "source": [ + "x = np.array([3, 4, 5])\n", + "y = np.array([1, 0, -1])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q22. Divide x by y element-wise in two different ways." + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3. 2. 1.66666667]\n", + "[ 3. 2. 1.]\n" + ] + } + ], + "source": [ + "x = np.array([3., 4., 5.])\n", + "y = np.array([1., 2., 3.])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q23. Compute numerical negative value of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1 1]\n" + ] + } + ], + "source": [ + "x = np.array([1, -1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q24. Compute the reciprocal of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1. 0.5 5. ]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., .2])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q25. Compute $x^y$, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 4]\n", + " [ 3 16]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2], [3, 4]])\n", + "y = np.array([[1, 2], [1, 2]])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q26. Compute the remainder of x / y element-wise in two different ways." + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 0 1 1 0 1]\n", + "[-1 0 -1 1 0 1]\n" + ] + } + ], + "source": [ + "x = np.array([-3, -2, -1, 1, 2, 3])\n", + "y = 2\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Miscellaneous" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q27. If an element of x is smaller than 3, replace it with 3.\n", + "And if an element of x is bigger than 7, replace it with 7." + ] + }, + { + "cell_type": "code", + "execution_count": 174, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[3 3 3 3 4 5 6 7 7 7]\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q28. Compute the square of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 176, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 4 1]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, -1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q29. Compute square root of x element-wise.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 177, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1. 2. 3.]\n" + ] + } + ], + "source": [ + "x = np.array([1., 4., 9.])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q30. Compute the absolute value of x." + ] + }, + { + "cell_type": "code", + "execution_count": 178, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 1]\n", + " [3 3]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, -1], [3, -3]])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q31. Compute an element-wise indication of the sign of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 181, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1 1 0 -1 -1]\n" + ] + } + ], + "source": [ + "x = np.array([1, 3, 0, -1, -3])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/9_Mathematical_functions_solutions.ipynb b/9_Mathematical_functions_solutions.ipynb new file mode 100644 index 0000000..ccad259 --- /dev/null +++ b/9_Mathematical_functions_solutions.ipynb @@ -0,0 +1,1193 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Mathematical functions" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'1.11.2'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "__author__ = \"kyubyong. kbpark.linguist@gmail.com. https://github.com/kyubyong\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Trigonometric functions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q1. Calculate sine, cosine, and tangent of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sine: [ 0. 0.84147098 -0.98803162 0.89399666]\n", + "cosine: [ 1. 0.54030231 0.15425145 -0.44807362]\n", + "tangent: [ 0. 1.55740772 -6.4053312 -1.99520041]\n" + ] + } + ], + "source": [ + "x = np.array([0., 1., 30, 90])\n", + "print \"sine:\", np.sin(x)\n", + "print \"cosine:\", np.cos(x)\n", + "print \"tangent:\", np.tan(x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q2. Calculate inverse sine, inverse cosine, and inverse tangent of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "inverse sine: [ 1.57079633 0. 1.57079633]\n", + "inverse cosine: [ 0. 1.57079633 0. ]\n", + "inverse tangent: [ 0.78539816 0. 0.78539816]\n" + ] + } + ], + "source": [ + "x = np.array([-1., 0, 1.])\n", + "print \"inverse sine:\", np.arcsin(x2)\n", + "print \"inverse cosine:\", np.arccos(x2)\n", + "print \"inverse tangent:\", np.arctan(x2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q3. Convert angles from radians to degrees." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-180. -90. 90. 180.]\n" + ] + } + ], + "source": [ + "x = np.array([-np.pi, -np.pi/2, np.pi/2, np.pi])\n", + "\n", + "out1 = np.degrees(x)\n", + "out2 = np.rad2deg(x)\n", + "assert np.array_equiv(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q4. Convert angles from degrees to radians." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-3.14159265 -1.57079633 1.57079633 3.14159265]\n" + ] + } + ], + "source": [ + "x = np.array([-180., -90., 90., 180.])\n", + "\n", + "out1 = np.radians(x)\n", + "out2 = np.deg2rad(x)\n", + "assert np.array_equiv(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Hyperbolic functions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q5. Calculate hyperbolic sine, hyperbolic cosine, and hyperbolic tangent of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1.17520119 0. 1.17520119]\n", + "[ 1.54308063 1. 1.54308063]\n", + "[-0.76159416 0. 0.76159416]\n" + ] + } + ], + "source": [ + "x = np.array([-1., 0, 1.])\n", + "print np.sinh(x)\n", + "print np.cosh(x)\n", + "print np.tanh(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rounding" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q6. Predict the results of these, paying attention to the difference among the family functions." + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2. 2. 2. 3. -2. -2. -3.]\n", + "[ 2. 1. 2. 2. -3. -3. -3.]\n", + "[ 3. 2. 3. 3. -2. -2. -2.]\n", + "[ 2. 1. 2. 2. -2. -2. -2.]\n", + "[2.0, 2.0, 3.0, 3.0, -2.0, -3.0, -3.0]\n" + ] + } + ], + "source": [ + "x = np.array([2.1, 1.5, 2.5, 2.9, -2.1, -2.5, -2.9])\n", + "\n", + "out1 = np.around(x)\n", + "out2 = np.floor(x)\n", + "out3 = np.ceil(x)\n", + "out4 = np.trunc(x)\n", + "out5 = [round(elem) for elem in x]\n", + "\n", + "print out1\n", + "print out2\n", + "print out3\n", + "print out4\n", + "print out5\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q7. Implement out5 in the above question using numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2. 2. 3. 3. -2. -3. -3.]\n" + ] + } + ], + "source": [ + "print np.floor(np.abs(x) + 0.5) * np.sign(x) \n", + "# Read http://numpy-discussion.10968.n7.nabble.com/why-numpy-round-get-a-different-result-from-python-round-function-td19098.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sums, products, differences" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q8. Predict the results of these." + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('->', 36)\n", + "('->', array([ 6, 8, 10, 12]))\n", + "('->', array([[10],\n", + " [26]]))\n", + "\n", + "('->', 40320)\n", + "('->', array([ 5, 12, 21, 32]))\n", + "('->', array([[ 24],\n", + " [1680]]))\n", + "\n", + "('->', array([ 1, 3, 6, 10, 15, 21, 28, 36]))\n", + "('->', array([[ 1, 2, 3, 4],\n", + " [ 6, 8, 10, 12]]))\n", + "('->', array([[ 1, 3, 6, 10],\n", + " [ 5, 11, 18, 26]]))\n", + "\n", + "('->', array([ 1, 2, 6, 24, 120, 720, 5040, 40320]))\n", + "('->', array([[ 1, 2, 3, 4],\n", + " [ 5, 12, 21, 32]]))\n", + "('->', array([[ 1, 2, 6, 24],\n", + " [ 5, 30, 210, 1680]]))\n", + "\n", + "('->', 1)\n", + "('->', array([1, 2, 3, 4]))\n", + "('->', array([[1],\n", + " [5]]))\n", + "\n", + "('->', 8)\n", + "('->', array([5, 6, 7, 8]))\n", + "('->', array([[4],\n", + " [8]]))\n", + "\n", + "('->', 4.5)\n", + "('->', array([ 3., 4., 5., 6.]))\n", + "('->', array([[ 2.5],\n", + " [ 6.5]]))\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python2.7/dist-packages/ipykernel/__main__.py:34: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n" + ] + } + ], + "source": [ + "x = np.array(\n", + " [[1, 2, 3, 4],\n", + " [5, 6, 7, 8]])\n", + "\n", + "outs = [np.sum(x),\n", + " np.sum(x, axis=0),\n", + " np.sum(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.prod(x),\n", + " np.prod(x, axis=0),\n", + " np.prod(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.cumsum(x),\n", + " np.cumsum(x, axis=0),\n", + " np.cumsum(x, axis=1),\n", + " \"\",\n", + " np.cumprod(x),\n", + " np.cumprod(x, axis=0),\n", + " np.cumprod(x, axis=1),\n", + " \"\",\n", + " np.min(x),\n", + " np.min(x, axis=0),\n", + " np.min(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.max(x),\n", + " np.max(x, axis=0),\n", + " np.max(x, axis=1, keepdims=True),\n", + " \"\",\n", + " np.mean(x),\n", + " np.mean(x, axis=0),\n", + " np.mean(x, axis=1, keepdims=True)]\n", + " \n", + "for out in outs:\n", + " if out == \"\":\n", + " print\n", + " else:\n", + " print(\"->\", out)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q9. Calculate the difference between neighboring elements, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1 2 3 -7]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 4, 7, 0])\n", + "print np.diff(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q10. Calculate the difference between neighboring elements, element-wise, and\n", + "prepend [0, 0] and append[100] to it." + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0 0 1 2 3 -7 100]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 4, 7, 0])\n", + "\n", + "out1 = np.ediff1d(x, to_begin=[0, 0], to_end=[100])\n", + "out2 = np.insert(np.append(np.diff(x), 100), 0, [0, 0])\n", + "assert np.array_equiv(out1, out2)\n", + "print out2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q11. Return the cross product of x and y." + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-3 6 -3]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3])\n", + "y = np.array([4, 5, 6])\n", + "\n", + "print np.cross(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exponents and logarithms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q12. Compute $e^x$, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2.71828175 7.38905621 20.08553696]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., 3.], np.float32)\n", + "\n", + "out = np.exp(x)\n", + "print out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q13. Calculate exp(x) - 1 for all elements in x." + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.71828175 6.38905621 19.08553696]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., 3.], np.float32)\n", + "\n", + "out1 = np.expm1(x)\n", + "out2 = np.exp(x) - 1.\n", + "assert np.allclose(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q14. Calculate $2^p$ for all p in x." + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2. 4. 8.]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., 3.], np.float32)\n", + "\n", + "out1 = np.exp2(x)\n", + "out2 = 2 ** x\n", + "assert np.allclose(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q15. Compute natural, base 10, and base 2 logarithms of x element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "natural log = [ 0. 1. 2.]\n", + "common log = [ 0. 0.43429448 0.86858896]\n", + "base 2 log = [ 0. 1.44269504 2.88539008]\n" + ] + } + ], + "source": [ + "x = np.array([1, np.e, np.e**2])\n", + "\n", + "print \"natural log =\", np.log(x)\n", + "print \"common log =\", np.log10(x)\n", + "print \"base 2 log =\", np.log2(x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q16. Compute the natural logarithm of one plus each element in x in floating-point accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.00000000e-099 1.00000000e-100]\n" + ] + } + ], + "source": [ + "x = np.array([1e-99, 1e-100])\n", + "\n", + "print np.log1p(x)\n", + "# Compare it with np.log(1 +x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Floating point routines" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q17. Return element-wise True where signbit is set." + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True True False False False False]\n" + ] + } + ], + "source": [ + "x = np.array([-3, -2, -1, 0, 1, 2, 3])\n", + "\n", + "out1 = np.signbit(x)\n", + "out2 = x < 0\n", + "assert np.array_equiv(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q18. Change the sign of x to that of y, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1. -0. -1.]\n" + ] + } + ], + "source": [ + "x = np.array([-1, 0, 1])\n", + "y = -1.1\n", + "\n", + "print np.copysign(x, y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Arithmetic operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q19. Add x and y element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 0 0]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3])\n", + "y = np.array([-1, -2, -3])\n", + "\n", + "out1 = np.add(x, y)\n", + "out2 = x + y\n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q20. Subtract y from x element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2]\n" + ] + } + ], + "source": [ + "x = np.array([3, 4, 5])\n", + "y = np.array(3)\n", + "\n", + "out1 = np.subtract(x, y)\n", + "out2 = x - y \n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q21. Multiply x by y element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3 0 -5]\n" + ] + } + ], + "source": [ + "x = np.array([3, 4, 5])\n", + "y = np.array([1, 0, -1])\n", + "\n", + "out1 = np.multiply(x, y)\n", + "out2 = x * y \n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q22. Divide x by y element-wise in two different ways." + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3. 2. 1.66666667]\n", + "[ 3. 2. 1.]\n" + ] + } + ], + "source": [ + "x = np.array([3., 4., 5.])\n", + "y = np.array([1., 2., 3.])\n", + "\n", + "out1 = np.true_divide(x, y)\n", + "out2 = x / y \n", + "assert np.array_equal(out1, out2)\n", + "print out1\n", + "\n", + "out3 = np.floor_divide(x, y)\n", + "out4 = x // y\n", + "assert np.array_equal(out3, out4)\n", + "print out3\n", + "\n", + "# Note that in Python 2 and 3, the handling of `divide` differs.\n", + "# See https://docs.scipy.org/doc/numpy/reference/generated/numpy.divide.html#numpy.divide\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q23. Compute numerical negative value of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1 1]\n" + ] + } + ], + "source": [ + "x = np.array([1, -1])\n", + "\n", + "out1 = np.negative(x)\n", + "out2 = -x\n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q24. Compute the reciprocal of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1. 0.5 5. ]\n" + ] + } + ], + "source": [ + "x = np.array([1., 2., .2])\n", + "\n", + "out1 = np.reciprocal(x)\n", + "out2 = 1/x\n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q25. Compute $x^y$, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 1 4]\n", + " [ 3 16]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, 2], [3, 4]])\n", + "y = np.array([[1, 2], [1, 2]])\n", + "\n", + "out = np.power(x, y)\n", + "print out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q26. Compute the remainder of x / y element-wise in two different ways." + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 0 1 1 0 1]\n", + "[-1 0 -1 1 0 1]\n" + ] + } + ], + "source": [ + "x = np.array([-3, -2, -1, 1, 2, 3])\n", + "y = 2\n", + "\n", + "out1 = np.mod(x, y)\n", + "out2 = x % y\n", + "assert np.array_equal(out1, out2)\n", + "print out1\n", + "\n", + "out3 = np.fmod(x, y)\n", + "print out3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Miscellaneous" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q27. If an element of x is smaller than 3, replace it with 3.\n", + "And if an element of x is bigger than 7, replace it with 7." + ] + }, + { + "cell_type": "code", + "execution_count": 174, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[3 3 3 3 4 5 6 7 7 7]\n" + ] + } + ], + "source": [ + "x = np.arange(10)\n", + "\n", + "out1 = np.clip(x, 3, 7)\n", + "out2 = np.copy(x)\n", + "out2[out2 < 3] = 3\n", + "out2[out2 > 7] = 7\n", + "\n", + "assert np.array_equiv(out1, out2)\n", + "print out1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q28. Compute the square of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 176, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 4 1]\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, -1])\n", + "\n", + "out1 = np.square(x)\n", + "out2 = x * x\n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q29. Compute square root of x element-wise.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 177, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1. 2. 3.]\n" + ] + } + ], + "source": [ + "x = np.array([1., 4., 9.])\n", + "\n", + "out = np.sqrt(x)\n", + "print out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q30. Compute the absolute value of x." + ] + }, + { + "cell_type": "code", + "execution_count": 178, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 1]\n", + " [3 3]]\n" + ] + } + ], + "source": [ + "x = np.array([[1, -1], [3, -3]])\n", + "\n", + "out = np.abs(x)\n", + "print out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Q31. Compute an element-wise indication of the sign of x, element-wise." + ] + }, + { + "cell_type": "code", + "execution_count": 181, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1 1 0 -1 -1]\n" + ] + } + ], + "source": [ + "x = np.array([1, 3, 0, -1, -3])\n", + "\n", + "out1 = np.sign(x)\n", + "out2 = np.copy(x)\n", + "out2[out2 > 0] = 1\n", + "out2[out2 < 0] = -1\n", + "assert np.array_equal(out1, out2)\n", + "print out1\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}