From a88b160f05b7fb8e4edfbdf645524483e0595e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20S=C3=A1ez?= Date: Mon, 28 Mar 2016 21:47:19 +0200 Subject: [PATCH] Added info about conda and basic NumPy --- Basic Python Packages for Science.ipynb | 615 +++++++++++++++++++++++- static/conda.png | Bin 0 -> 6096 bytes 2 files changed, 611 insertions(+), 4 deletions(-) create mode 100644 static/conda.png diff --git a/Basic Python Packages for Science.ipynb b/Basic Python Packages for Science.ipynb index 8eb717f..ebe820e 100644 --- a/Basic Python Packages for Science.ipynb +++ b/Basic Python Packages for Science.ipynb @@ -41,21 +41,56 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "##### Optimizing what?" + "##### Principal Python Packages for scientific purposes " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "##### Principal Python Packages for scientific purposes " + "##### Anaconda & conda" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![conda](./static/conda.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "##### Anaconda " + "http://conda.pydata.org/docs/intro.html\n", + "\n", + "Conda is a package manager application that quickly installs, runs, and updates packages and their dependencies. The conda command is the primary interface for managing installations of various packages. It can query and search the package index and current installation, create new environments, and install and update packages into existing conda environments. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import HTML\n", + "HTML('')" ] }, { @@ -65,6 +100,22 @@ "##### Main objectives of this workshop " ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* Provide you with a first insight into the principal Python tools & libraries used in Science:\n", + " - conda.\n", + " - Jupyter Notebook.\n", + " - NumPy, matplotlib, SciPy\n", + "* Provide you with the basic skills to face basic tasks such as:\n", + " - \n", + "* Show other common libraries:\n", + " - Pandas, scikit-learn (some talks & workshops will focus on these packages)\n", + " - SymPy\n", + " - Numba ¿?" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -93,9 +144,36 @@ "![numpy-logo](./static/numpy.png)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### ndarray object " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| index | 0 | 1 | 2 | 3 | ... | n-1 | n |\n", + "| ---------- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n", + "| value | 2.1 | 3.6 | 7.8 | 1.5 | ... | 5.4 | 6.3 |" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* N-dimensional data structure.\n", + "* Homogeneously typed.\n", + "* Efficient!\n", + "\n", + "A universal function (or ufunc for short) is a function that operates on ndarrays. It is a “vectorized function\"." + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "collapsed": true }, @@ -104,6 +182,535 @@ "import numpy as np" ] }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1000 loops, best of 3: 1.54 ms per loop\n" + ] + } + ], + "source": [ + "my_list = list(range(0,100000))\n", + "%timeit sum(my_list)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The slowest run took 6.73 times longer than the fastest. This could mean that an intermediate result is being cached.\n", + "10000 loops, best of 3: 95.7 µs per loop\n" + ] + } + ], + "source": [ + "array = np.arange(0, 100000)\n", + "%timeit np.sum(array)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Array creation" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2, 3, 4])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "one_dim_array = np.array([1, 2, 3, 4])\n", + "one_dim_array" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1, 2, 3],\n", + " [4, 5, 6],\n", + " [7, 8, 9]])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array = np.array([[1, 2, 3],\n", + " [4, 5, 6],\n", + " [7, 8, 9]])\n", + "two_dim_array" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array.size" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(3, 3)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "dtype('int64')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array.dtype" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "zeros_arr = np.zeros([3, 3])\n", + "ones_arr = np.ones([10])\n", + "eye_arr = np.eye(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "range_arr = np.arange(15)\n", + "range_arr" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 1, 2, 3, 4],\n", + " [ 5, 6, 7, 8, 9],\n", + " [10, 11, 12, 13, 14]])" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "range_arr.reshape([3, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. ,\n", + " 4.5, 5. , 5.5, 6. , 6.5, 7. , 7.5, 8. , 8.5,\n", + " 9. , 9.5, 10. ])" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linspace(0, 10, 21)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Basic slicing " + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2.5" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "one_dim_array[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "91" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array[-1, -1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`[start:stop:step]`" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,\n", + " 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,\n", + " 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98])" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_arr = np.arange(100)\n", + "my_arr[0::2]" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0, 1, 0, 1, 0, 1, 0, 1],\n", + " [1, 0, 1, 0, 1, 0, 1, 0],\n", + " [0, 1, 0, 1, 0, 1, 0, 1],\n", + " [1, 0, 1, 0, 1, 0, 1, 0],\n", + " [0, 1, 0, 1, 0, 1, 0, 1],\n", + " [1, 0, 1, 0, 1, 0, 1, 0],\n", + " [0, 1, 0, 1, 0, 1, 0, 1],\n", + " [1, 0, 1, 0, 1, 0, 1, 0]])" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chess_board = np.zeros([8, 8], dtype=int)\n", + "\n", + "chess_board[0::2, 1::2] = 1\n", + "chess_board[1::2, 0::2] = 1\n", + "\n", + "chess_board" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Operations & linalg " + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x = np.linspace(0, 10)\n", + "y = np.sin(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/miniconda/envs/pydata-basic-python/lib/python3.5/site-packages/ipykernel/__main__.py:1: RuntimeWarning: divide by zero encountered in log\n", + " if __name__ == '__main__':\n" + ] + } + ], + "source": [ + "y_2 = (1 + np.log(x)) ** 2" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[10, 40, 77],\n", + " [25, 25, 68],\n", + " [33, 16, 91]])" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array = np.array([[10, 25, 33],\n", + " [40, 25, 16],\n", + " [77, 68, 91]])\n", + "\n", + "two_dim_array.T" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 3641, 3119, 3733],\n", + " [ 2632, 2713, 3176],\n", + " [10497, 9813, 11910]])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_dim_array @ two_dim_array" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 240.4, 250.8, 783.1])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "one_dim_array = np.array([2.5, 3.6, 3.8])\n", + "\n", + "two_dim_array @ one_dim_array" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-0.05372256, 0.00140303, 0.01923512],\n", + " [ 0.10898393, 0.07381761, -0.05250057],\n", + " [-0.03598099, -0.05634759, 0.03394433]])" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.inv(two_dim_array)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 133.6946629, -17.266221 , 9.5715581]),\n", + " array([[-0.29580975, -0.74274264, 0.0661375 ],\n", + " [-0.24477775, 0.65983255, -0.79576005],\n", + " [-0.92335283, 0.1138173 , 0.60198985]]))" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.eig(two_dim_array)" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/static/conda.png b/static/conda.png new file mode 100644 index 0000000000000000000000000000000000000000..4f7f0de2d67be25655e08d23267d06e94e93bfc1 GIT binary patch literal 6096 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 WsC7FpEvxAO0000