{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Vectorized Code\n",
    "\n",
    "Always prefer builtin functions and operators to for loops. They are **much more efficient**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.7979159  0.96836573 0.20664445 0.62135717 0.87544718 0.60766259\n",
      " 0.27853697 0.08548639 0.86701681 0.77239239 0.29827174 0.65149195\n",
      " 0.1794432  0.27125414 0.50458605 0.0865881  0.93080258 0.07003178\n",
      " 0.13422815 0.39212578]\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAD8CAYAAABw1c+bAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAFtVJREFUeJzt3X+w3XV95/Hny5jaiKyxcv1BIIadpRmtCHHvBJ3sqLRdEpgqlHG6UEttBzeDo7vaZTML7ozu6B+wy9TOOmo1WxlqR3HdGiJTUcgsdhEVNCEgPyJtFmnNDVMiyA9rVg197x/nXHK43B/fe++555zc7/MxcybnfL+fc877fOfmdb/38/2czydVhSSpPZ437AIkSYNl8EtSyxj8ktQyBr8ktYzBL0ktY/BLUssY/JLUMga/JLWMwS9JLfP8YRcwnRNOOKHWrVs37DIk6ZixZ8+eH1XVWJO2cwZ/kl8GbgVe0G3/l1X1oSltXgB8FviXwKPAv6mqh7r7rgAuAZ4G/n1V3TTXe65bt47du3c3qV+SBCT5u6Ztm3T1/Az49ao6HTgD2JLkDVPaXAL8uKr+BfAnwH/tFvIa4ELg14AtwCeTrGhanCSp/+YM/ur4Sffhyu5t6sxu5wF/3r3/l8BvJEl3+xeq6mdV9QNgP7CxL5VLkhak0cXdJCuS3AU8AuyqqjumNFkD/BCgqo4ATwAv7d3edaC7TZI0JI2Cv6qerqozgJOAjUleO6VJpnvaLNufI8nWJLuT7D506FCTsiRJCzCv4ZxV9Tjw13T663sdAE4GSPJ84MXAY73bu04CDs7w2turaryqxsfGGl2YliQtwJzBn2Qsyeru/VXAbwLfn9LsBuCd3ftvB26pzgovNwAXJnlBklOAU4Hv9Kt4SdL8NRnH/0rgz7ujcZ4HfLGq/irJh4HdVXUD8BngL5Lsp3OmfyFAVd2X5IvA/cAR4D1V9fRSfBBJUjMZxaUXx8fHy3H8ko4lO/dOcPVND3Dw8cOcuHoV2zav5/wNgxvLkmRPVY03aTuS39yVpGPJzr0TXLHjHg7/otOhMfH4Ya7YcQ/AQMO/KefqkaRFuvqmB54J/UmHf/E0V9/0wJAqmp3BL0mLdPDxw/PaPmwGvyQt0omrV81r+7AZ/JK0SNs2r2fVymdPQ7Zq5Qq2bV4/43N27p1g01W3cMrlX2HTVbewc+/EUpf5DC/uStIiTV7AbTqqZ9gXgw1+SeqD8zesaRzas10MHkTw29UjSQM27IvBBr8kDdiwLwYb/JI0YAu5GNxP9vFL0oDN92Jwvxn8kjQE87kY3G929UhSyxj8ktQyBr8ktYzBL0ktY/BLUsvMOaonycnAZ4FXAP8EbK+q/z6lzTbgHT2v+WpgrKoeS/IQ8BTwNHCk6QoxkqSl0WQ45xHgsqq6M8nxwJ4ku6rq/skGVXU1cDVAkrcCf1RVj/W8xllV9aN+Fi5JWpg5u3qq6uGqurN7/ylgHzDb4NOLgOv6U54kqd/m9QWuJOuADcAdM+x/IbAFeG/P5gJuTlLAp6tq+4IqlaQ+GfbC6MPWOPiTvAj4EvD+qnpyhmZvBb45pZtnU1UdTPIyYFeS71fVrdO8/lZgK8DatWsbfwBJmo9hz4U/ChqN6kmykk7of66qdszS9EKmdPNU1cHuv48A1wMbp3tiVW2vqvGqGh8bG2tSliTN20xz4V/2xbsHugrWMM0Z/EkCfAbYV1UfnaXdi4E3A1/u2XZc94IwSY4DzgbuXWzRkrRQM815/3QVV+y4pxXh3+SMfxNwMfDrSe7q3s5NcmmSS3va/TZwc1X9Y8+2lwO3Jbkb+A7wlar6Wt+ql6R5mm3O+8lVsJa7Ofv4q+o2IA3aXQtcO2Xbg8DpC6xNkvpu2+b1z+rjn2pQq2ANk9/cldQq529Yw5UXnMaKTH8+O6hVsIbJ4JfUOudvWMMf/87pQ10Fa5hciEVSKw17FaxhMvgltdYwV8EaJrt6JKllDH5JahmDX5JaxuCXpJYx+CWpZRzVI2kktX3q5KVk8EsaOU6dvLTs6pE0cmaaOrkNE6gNgsEvaeTMNFFaGyZQGwSDX9LImWmitDZMoDYIBr+kkbNt8/rWTqA2CF7clTRy2jyB2iAY/JJGUlsnUBuEJmvunpzk60n2JbkvyfumafOWJE/0LM34wZ59W5I8kGR/ksv7/QEkSfPT5Iz/CHBZVd3ZXTh9T5JdVXX/lHbfqKrf6t2QZAXwCeBfAweA7ya5YZrnSpIGZM4z/qp6uKru7N5/CtgHNP37ayOwv6oerKqfA18AzltosZKkxZvXqJ4k64ANwB3T7H5jkruTfDXJr3W3rQF+2NPmAM1/aUiSlkDji7tJXgR8CXh/VT05ZfedwKuq6idJzgV2AqcC061mXDO8/lZgK8DatWubliVJmqdGZ/xJVtIJ/c9V1Y6p+6vqyar6Sff+jcDKJCfQOcM/uafpScDB6d6jqrZX1XhVjY+Njc3zY0g6luzcO8Gmq27hlMu/wqarbmHn3olhl9Qqc57xJwnwGWBfVX10hjavAP6hqirJRjq/UB4FHgdOTXIKMAFcCPxuv4qXdOxxArbha9LVswm4GLgnyV3dbR8A1gJU1aeAtwPvTnIEOAxcWFUFHEnyXuAmYAVwTVXd1+fPIOkYMtsEbAb/YMwZ/FV1G9P31fe2+Tjw8Rn23QjcuKDqJC07TsA2fM7VI2mgnIBt+Ax+SQPlBGzD51w9kgbKCdiGz+CXNHBOwDZcdvVIUssY/JLUMnb1SCNq594J+8G1JAx+aQT57VYtJbt6pBE027dbpcUy+KUR5LdbtZQMfmkE+e1WLSWDXxpBfrtVS8mLu9II8tutWkoGvzSi/HarlopdPZLUMga/JLWMwS9JLTNn8Cc5OcnXk+xLcl+S903T5h1Jvte9fSvJ6T37HkpyT5K7kuzu9weQJM1Pk4u7R4DLqurOJMcDe5Lsqqr7e9r8AHhzVf04yTnAduDMnv1nVdWP+le2JGmhmqy5+zDwcPf+U0n2AWuA+3vafKvnKbcDJ/W5TklSn8xrOGeSdcAG4I5Zml0CfLXncQE3Jyng01W1fZ41SponZ/bUbBoHf5IXAV8C3l9VT87Q5iw6wf+vejZvqqqDSV4G7Ery/aq6dZrnbgW2Aqxdu3YeH0FSL2f21FwajepJspJO6H+uqnbM0OZ1wJ8B51XVo5Pbq+pg999HgOuBjdM9v6q2V9V4VY2PjY3N71NIeoYze2ouTUb1BPgMsK+qPjpDm7XADuDiqvqbnu3HdS8Ik+Q44Gzg3n4ULml6zuypuTTp6tkEXAzck+Su7rYPAGsBqupTwAeBlwKf7Pye4EhVjQMvB67vbns+8Pmq+lpfP4GkZzlx9Sompgl5Z/bUpCajem4DMkebdwHvmmb7g8Dpz32GpIVoctF22+b1z+rjB2f21LM5SZt0jGh60daZPTUXg186Rsx20XZqqDuzp2bjXD3SMcKLtuoXg186Rrgco/rF4JeOES7HqH6xj186RnjRVv1i8EvHEC/aqh/s6pGkljH4JallDH5JahmDX5JaxuCXpJYx+CWpZQx+SWoZg1+SWsbgl6SWMfglqWWarLl7cpKvJ9mX5L4k75umTZJ8LMn+JN9L8vqefe9M8rfd2zv7/QEkSfPTZK6eI8BlVXVnd+H0PUl2VdX9PW3OAU7t3s4E/hQ4M8mvAB8CxoHqPveGqvpxXz+FJKmxOc/4q+rhqrqze/8pYB8wdZao84DPVsftwOokrwQ2A7uq6rFu2O8CtvT1E0iS5mVeffxJ1gEbgDum7FoD/LDn8YHutpm2S5KGpHHwJ3kR8CXg/VX15NTd0zylZtk+3etvTbI7ye5Dhw41LUuSNE+Ngj/JSjqh/7mq2jFNkwPAyT2PTwIOzrL9Oapqe1WNV9X42NhYk7IkSQvQZFRPgM8A+6rqozM0uwH4/e7onjcAT1TVw8BNwNlJXpLkJcDZ3W2SpCFpMqpnE3AxcE+Su7rbPgCsBaiqTwE3AucC+4GfAn/Y3fdYko8A3+0+78NV9Vj/ypckzdecwV9VtzF9X31vmwLeM8O+a4BrFlSdJKnvXHNXmmLn3gkXNNeyZvBLPXbuneCKHfdw+BdPAzDx+GGu2HEPgOGvZcO5eqQeV9/0wDOhP+nwL57m6pseGFJFUv95xq+hGrVulYOPH57XdulY5Bm/hmayW2Xi8cMUR7tVdu6dGFpNJ65eNa/t0rHI4NfQjGK3yrbN61m1csWztq1auYJtm9cPqSKp/+zq0dCMYrfKZDfTKHU/Sf1m8GtoTly9iolpQn7Y3Srnb1hj0GtZs6tHQ2O3ijQcnvFraOxWkYbD4NdQ2a0iDZ5dPZLUMga/JLWMwS9JLWPwS1LLGPyS1DIGvyS1zJzDOZNcA/wW8EhVvXaa/duAd/S83quBse6yiw8BTwFPA0eqarxfhat/Rm2GTElLq8kZ/7XAlpl2VtXVVXVGVZ0BXAH8nynr6p7V3W/oj6BRnCFT0tKaM/ir6lag6QLpFwHXLaoiDdQozpApaWn1rY8/yQvp/GXwpZ7NBdycZE+Srf16L/XPKM6QKWlp9fPi7luBb07p5tlUVa8HzgHek+RNMz05ydYku5PsPnToUB/L0mxceERqn34G/4VM6eapqoPdfx8Brgc2zvTkqtpeVeNVNT42NtbHsjQbZ8iU2qcvwZ/kxcCbgS/3bDsuyfGT94GzgXv78X7qn/M3rOHKC05jzepVBFizehVXXnCao3qkZazJcM7rgLcAJyQ5AHwIWAlQVZ/qNvtt4Oaq+seep74cuD7J5Pt8vqq+1r/S1S/OkCm1y5zBX1UXNWhzLZ1hn73bHgROX2hh6i/H6kua5Hz8LTA5Vn9y2ObkWH3A8JdayCkbWsCx+pJ6Gfwt4Fh9Sb0M/hZwrL6kXgZ/CzhWX1IvL+62wOQFXEf1SAKDvzUcqy9pkl09ktQyBr8ktYzBL0ktY/BLUssY/JLUMga/JLWMwS9JLWPwS1LLGPyS1DIGvyS1zJzBn+SaJI8kmXa93CRvSfJEkru6tw/27NuS5IEk+5Nc3s/CJUkL0+SM/1pgyxxtvlFVZ3RvHwZIsgL4BHAO8BrgoiSvWUyxkqTFmzP4q+pW4LEFvPZGYH9VPVhVPwe+AJy3gNeRJPVRv2bnfGOSu4GDwH+sqvuANcAPe9ocAM7s0/upIRdZlzRVP4L/TuBVVfWTJOcCO4FTgUzTtmZ6kSRbga0Aa9eu7UNZcpF1SdNZ9Kieqnqyqn7SvX8jsDLJCXTO8E/uaXoSnb8IZnqd7VU1XlXjY2Njiy3rmLNz7wSbrrqFUy7/CpuuuoWdeycW/Zousi5pOos+40/yCuAfqqqSbKTzy+RR4HHg1CSnABPAhcDvLvb9lqOlOjN3kXVJ02kynPM64NvA+iQHklyS5NIkl3abvB24t9vH/zHgwuo4ArwXuAnYB3yx2/evKZbqzNxF1iVNZ84z/qq6aI79Hwc+PsO+G4EbF1ZaeyzVmfm2zeuf9ZcEuMi6JL+5OxKW6sz8/A1ruPKC01izehUB1qxexZUXnOaFXanlXGx9BCzlmbmLrEuayuAfAZPB7Hh7SYNg8I8Iz8wlDYp9/JLUMga/JLWMXT0D4Hw5kkaJwb/EnC9H0qixq2eJOV+OpFFj8C8x58uRNGoM/iXmfDmSRo3Bv8S2bV7PqpUrnrXN+XIkDZMXd5eY38qVNGoM/gHwW7mSRoldPZLUMga/JLWMwS9JLdNk6cVrkjyS5N4Z9r8jyfe6t28lOb1n30NJ7klyV5Ld/SxckrQwTc74rwW2zLL/B8Cbq+p1wEeA7VP2n1VVZ1TV+MJKlCT1U5M1d29Nsm6W/d/qeXg7cNLiy+o/J0qTpI5+9/FfAny153EBNyfZk2Rrn9+rscmJ0iYeP0xxdKK0nXsnhlWSJA1N34I/yVl0gv8/9WzeVFWvB84B3pPkTbM8f2uS3Ul2Hzp0qF9lAU6UJkm9+hL8SV4H/BlwXlU9Orm9qg52/30EuB7YONNrVNX2qhqvqvGxsbF+lPUMJ0qTpKMWHfxJ1gI7gIur6m96th+X5PjJ+8DZwLQjg5aaE6VJ0lFNhnNeB3wbWJ/kQJJLklya5NJukw8CLwU+OWXY5suB25LcDXwH+EpVfW0JPsOcnChNko5qMqrnojn2vwt41zTbHwROf+4zBs+J0iTpqNZM0rbYidIcDippuWhN8C+G6+ZKWk6cq6cBh4NKWk5ac8a/mK4ah4NKWk5acca/2G/uOhxU0nLSiuBfbFeNw0ElLSet6OpZbFeNw0ElLSetCP4TV69iYpqQn09XjevmSlouWtHVY1eNJB3VijN+u2ok6ahWBD/YVSNJk5Zl8Du9giTNbNkFv9MrSNLslt3FXadXkKTZLbvgd3oFSZrdsgt+p1eQpNktu+B3zL4kza5R8Ce5JskjSaZdMzcdH0uyP8n3kry+Z987k/xt9/bOfhU+k/M3rOHKC05jzepVBFizehVXXnCaF3YlqavpqJ5rgY8Dn51h/znAqd3bmcCfAmcm+RXgQ8A4UMCeJDdU1Y8XU/RcHLMvSTNrdMZfVbcCj83S5Dzgs9VxO7A6ySuBzcCuqnqsG/a7gC2LLVqStHD96uNfA/yw5/GB7raZtkuShqRfwZ9pttUs25/7AsnWJLuT7D506FCfypIkTdWv4D8AnNzz+CTg4Czbn6OqtlfVeFWNj42N9aksSdJU/Qr+G4Df747ueQPwRFU9DNwEnJ3kJUleApzd3SZJGpJGo3qSXAe8BTghyQE6I3VWAlTVp4AbgXOB/cBPgT/s7nssyUeA73Zf6sNVNdtFYknSEmsU/FV10Rz7C3jPDPuuAa6Zf2mSpKWQTmaPliSHgL8bdh0DdgLwo2EXMQI8Dkd5LDo8DkfNdixeVVWNLpCOZPC3UZLdVTU+7DqGzeNwlMeiw+NwVL+OxbKbq0eSNDuDX5JaxuAfHduHXcCI8Dgc5bHo8Dgc1ZdjYR+/JLWMZ/yS1DIG/4Al2ZLkge7aBZdPs/8/JLm/u67B/07yqmHUudTmOg497d6epJIs21EdTY5Fkt/p/lzcl+Tzg65xEBr831ib5OtJ9nb/f5w7jDqX2mLWP2msqrwN6AasAP4v8M+BXwLuBl4zpc1ZwAu7998N/M9h1z2M49BtdzxwK3A7MD7suof4M3EqsBd4Sffxy4Zd95COw3bg3d37rwEeGnbdS3Qs3gS8Hrh3hv3nAl+lMwnmG4A75vsenvEP1kZgf1U9WFU/B75AZy2DZ1TV16vqp92Ht9OZ2G65mfM4dH0E+G/A/xtkcQPW5Fj8W+AT1V3AqKoeGXCNg9DkOBTwz7r3X8wMEz4e62rh6580ZvAP1nzXJ7iEzm/25WbO45BkA3ByVf3VIAsbgiY/E78K/GqSbya5PclyXMyoyXH4L8DvdecLuxH4d4MpbeQsep2Tpksvqj/msz7B79FZsvLNS1rRcMx6HJI8D/gT4A8GVdAQNfmZeD6d7p630PkL8BtJXltVjy9xbYPU5DhcBFxbVX+c5I3AX3SPwz8tfXkjpXGOzMQz/sFqtD5Bkt8E/jPwtqr62YBqG6S5jsPxwGuBv07yEJ1+zBuW6QXeJj8TB4AvV9UvquoHwAN0fhEsJ02OwyXAFwGq6tvAL9OZu6ZtGq9zMhODf7C+C5ya5JQkvwRcSGctg2d0uzg+TSf0l2NfLsxxHKrqiao6oarWVdU6Otc63lZVu4dT7pKa82cC2Ennoj9JTqDT9fPgQKtcek2Ow98DvwGQ5NV0gr+Ny/XNtP5JY3b1DFBVHUnyXjqL0awArqmq+5J8GNhdVTcAVwMvAv5XEoC/r6q3Da3oJdDwOLRCw2MxuaDR/cDTwLaqenR4Vfdfw+NwGfA/kvwRna6NP6juMJflZKHrn8zrPZbhcZMkzcKuHklqGYNfklrG4JekljH4JallDH5JahmDX5JaxuCXpJYx+CWpZf4/cxmmv5kXwz4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "theta0 = 1\n",
    "theta1 = 2\n",
    "\n",
    "n = 20\n",
    "\n",
    "x = np.random.rand(n)\n",
    "y = theta0 + theta1*x + 0.1*np.random.randn(n)\n",
    "\n",
    "plt.scatter(x,y)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.13544506967538034\n",
      "0.1354450696753803\n"
     ]
    }
   ],
   "source": [
    "# Compute the cost\n",
    "pred = theta0 + theta1*x\n",
    "\n",
    "residual = y - pred\n",
    "cost = np.sum(residual**2)\n",
    "\n",
    "cost2 = np.dot(residual, residual)\n",
    "\n",
    "print (cost)\n",
    "print (cost2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.22467306247087163\n"
     ]
    }
   ],
   "source": [
    "print(np.sum( (theta0 + theta1*x - y)**2 )) # one liner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Takeaway: do not use for loops if possible\n",
    "\n",
    "* There are many functions / operators available for elementwise and summary operations on arrays. Find them and use them!\n",
    "\n",
    "* Sometimes you can use linear algebra to compute what you want!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n",
      "45\n"
     ]
    }
   ],
   "source": [
    "# Example\n",
    "A = np.array([[1, 2, 3], [4, 5, 6], [7,8, 9]])\n",
    "\n",
    "print(A)\n",
    "print(np.sum(A))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n",
      "[12 15 18]\n"
     ]
    }
   ],
   "source": [
    "print(A)\n",
    "print(np.sum(A, axis=0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n",
      "[ 6 15 24]\n"
     ]
    }
   ],
   "source": [
    "print(A)\n",
    "print(np.sum(A, axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Array slicing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1, 2, 3], [4, 5, 6], [7,8, 9]])\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3]\n"
     ]
    }
   ],
   "source": [
    "# Get first row of A\n",
    "print(A[0, :])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 5 8]\n"
     ]
    }
   ],
   "source": [
    "# Get second column of A\n",
    "print(A[:, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [10 11 12]]\n"
     ]
    }
   ],
   "source": [
    "# Assign to third row of A\n",
    "A[2,:] = [10, 11, 12]\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 5  6]\n",
      " [11 12]]\n"
     ]
    }
   ],
   "source": [
    "# Get lower right block of A\n",
    "print(A[1:3, 1:3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Logical indexing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[False False False  True  True  True  True  True False False False]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1])\n",
    "\n",
    "i = x >= 4  # elementwise comparison\n",
    "\n",
    "print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5 6 5 4 3 2 1]\n",
      "[False False False  True  True  True  True  True False False False]\n",
      "[4 5 6 5 4]\n"
     ]
    }
   ],
   "source": [
    "print(x)\n",
    "print(i)\n",
    "print(x[i]) # select entries of x for which i is true"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4 5 6 5 4]\n"
     ]
    }
   ],
   "source": [
    "print(x[x>=4]) # one-liner"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3 4 5]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1, 2, 3, 4, 5])\n",
    "b = np.array([5, 4, 3, 2, 1])\n",
    "print(a[ a >= b ]) # What does this print?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "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.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
