diff --git a/Python for Data Science Tutorial.ipynb b/Python for Data Science Tutorial.ipynb new file mode 100644 index 0000000..724f087 --- /dev/null +++ b/Python for Data Science Tutorial.ipynb @@ -0,0 +1,2508 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Python for Data Science\n", + "#### By Charles Yang" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Table Of Contents\n", + "1. [Intro](#Intro)\n", + "2. [Abstraction and Disclaimers](#Abstraction)\n", + "3. [Function Definition](#Functions)\n", + "4. [Loops](#Loops)\n", + "5. [A quick intro to Pandas](#Pandas)\n", + "6. [A quick intro to Matplotlib](#Matplotlib)\n", + "7. [A quick intro to Scikit-Learn](#Sklearn)\n", + "8. [Python as a programming language(super optional)](#Python)\n", + "9. [Resource List](#Resource)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Intro'></a>\n", + "## Intro\n", + "Welcome to this quick tutorial on Python for Data Science. This is designed to be a **super quick crash course** style introduction - brevity and simplicity will be favored over an in depth discussion. Think of this as a quick launchpad to get you started and point you in the right direction. \n", + "\n", + "This tutorial will be heavily structured on example code that performs a variety of functions that you may find useful in the future. We will provide comments explaining what each function/method call does, but will not walk through each minute detail. We do spend some time diving into Panda's documentation to walk you through how to read documentation, which is a much more important skill than memorizing tons of syntax. But the best teacher is experience - we hope that this notebook will encourage you to jump into the unknown and embrace the mysteriousness of data science.\n", + "\n", + "Prereqs: basic understanding of Python and programming in general. A willingness to learn on your own. No math required!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Abstraction'></a>\n", + "## Abstraction\n", + "One of the most powerful concepts in Computer Science is **Abstraction**. Simply put, Abstraction is the idea that we can ignore how methods are implemented - all we need to understand are the inputs and outputs. Abstraction is a major contributing factor to the proliferation of open source packages and software. Rather than focusing on how the underlying code works, we simply **trust** that it will work. As a result, incredibly complex software can be used by anyone who understands the inputs and outputs. It is also partially responsible for the highly collaborative and open-source nature of CS. Simply by sharing a few kb of text files can save others development time and allow anyone anywhere to reproduce and build upon your work.\n", + "\n", + "Now it might seem like a slightly scary idea to trust code written by people you've never met. Even more frightening, we don't even know how it works! Of course, there are caveats. We should always ensure that the source code is reliable(number of users/developers is generally a good metric) - definitely don't go around the interwebs downloading every snippet of code you find. But generally, abstraction will be a powerful tool that will save us oodles of time.\n", + "\n", + "This notebook will draw on abstraction very heavily, probably slightly more than is healthy, in the hope that the resulting material will be simple enough for people of all levels to understand quickly. But for the most part, we will trust abstraction to do the heavy lifting for us and that the various packages we use do what they promised us.\n", + "\n", + "## Disclaimers \n", + "\n", + "So some important disclaimers up front:\n", + "\n", + "1) This is definitely not a notebook to learn programming. We will skip over many important ideas(most egregiously, recursion), especially those that tend to show up less often in data analysis.\n", + "\n", + "2) This is probably not the best notebook to learn Python. We are focusing on *packages in Python*, not Python itself. Yes, everything will be written in Python, so at least you will learn syntax, but we will skip over many important tools built into Python in favor of focusing exclusively on data science packages. For resources on where to learn Python specifically, jump to to the [Resources Section](#Resource)\n", + "\n", + "And with that, let's jump into Python!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Functions'></a>\n", + "## Defining Functions\n", + "Programming through functions( a.k.a. functional programming) will be the primary method used throughout this connector. For those of you in CS61A, you will later learn about Object Oriented Programming, another very popular and powerful method of building and organizing software. However, in this class, we will work almost exclusively with functions. To read more about functions, try [John Denero's textbook chapter on functions](http://composingprograms.com/pages/13-defining-new-functions.html)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "'''This cell imports all functions that will be needed for this notebook. \n", + "Don't worry, we re-import the packages as they are needed in the notebook in case you missed this cell'''\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import sklearn\n", + "'''This is a common magic function in IPython(which is the backend of jupyter notebooks). \n", + "It essentially tells matplotlib to display plots directly beneath the cell and to store the graph when printing\n", + "(http://ipython.readthedocs.io/en/stable/interactive/plotting.html)'''\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#A very simple function, no inputs\n", + "def HelloWorld():\n", + " print(\"Hello World\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "When we run the above cell, nothing happens! Why don't we try to call the function HelloWorld so that it executes" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello World\n" + ] + } + ], + "source": [ + "HelloWorld()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is a crucial distinction. Defining a function is like creating a new tool. Obviously, to use a tool, you must create one first, but until the time is right for you to actually use(call) it, it will simply be lying in the shed. To execute/use/call a function, we use the () notation, with any necessary formal parameters.\n", + "\n", + "Now what if we want a variable, say a, to be assigned the value of \"Hello World\"? If we want to be able to assign a variable to the value the function evaluates to, then we need to make use of the 'return' statement. In contrast to the print statement, the return statement is only used within functions and essentially says \"Any variable assigned to the output of this function will take on the value I return\". \n", + "\n", + "Let's see an example and try to assign a value to a function that only returns a print statement" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello World\n", + "None\n", + "This is the value of b: The world is your oyster\n" + ] + } + ], + "source": [ + "def returningTheWorld():\n", + " return \"The world is your oyster\"\n", + "a = HelloWorld()\n", + "b = returningTheWorld()\n", + "\n", + "print(a)\n", + "print(\"This is the value of b: \" + b)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n", + "35\n" + ] + } + ], + "source": [ + "def adder(x):\n", + " return x+7\n", + "def multiplier(x):\n", + " return 7*x\n", + "print(adder(5))\n", + "print(multiplier(5))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1029" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Higher Order Functions - treating functions as inputs\n", + "def composition_function(f,x):\n", + " return f(f(f(x)))\n", + "composition_function(multiplier,3)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<function __main__.HelloWorld>" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "HelloWorld" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ok well that didn't work either. Python is returning this weird statement \"<function ....>\".\n", + "What we've done is actually print out the function object. Functions are first class objects in Python, meaning they can be manipulated just as variables can. What this allows us to do " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A note on Object Oriented Programming(OOP): Given the brevity of this notebook, we will not be jumping into classes and methods. What is important to know is that \n", + "1. Objects are treated as manipulable data and are anything that are not primitives(e.g. boolean, strings, integer/float, etc). For instance, functions are objects. Objects can also be considered an array of associated functions that are grouped together.\n", + "2. OOP is an incredibly important idea in Computer Science. As a result, many of the packages we will use are built around OOP. But thanks to abstraction, you don't really need to understand OOP to actually use it (although if you do plan on going into this field and/or using computers, OOP is definitely something you need to learn.\n", + "3. With that said, here's what you need to know about the OOP we will have to understand. \n", + " 1. Pandas DataFrames(see below) and Matplotlib figures and axes(see below) are all objects, with associated functions\n", + " 2. As we saw above, functions need to have objects/parameters passed into them with the () notation.\n", + " 3. The crucial distinction is that OOP in Python uses the dot notation, where the first parameter, which is the object we are manipulating, is not passed into directly." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "<a id='Loops'></a>\n", + "## Loops\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [ + "for i in range(10):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [ + "i = 0\n", + "while i < 10:\n", + " print(i)\n", + " i = i+1" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This is: 0\n", + "This is: 10\n", + "\n", + "\n", + "This is: 1\n", + "This is: 11\n", + "\n", + "\n", + "This is: 2\n", + "This is: 12\n", + "\n", + "\n", + "This is: 3\n", + "This is: 13\n", + "\n", + "\n", + "This is: 4\n", + "This is: 14\n", + "\n", + "\n", + "This is: 5\n", + "This is: 15\n", + "\n", + "\n", + "This is: 6\n", + "This is: 16\n", + "\n", + "\n", + "This is: 7\n", + "This is: 17\n", + "\n", + "\n", + "This is: 8\n", + "This is: 18\n", + "\n", + "\n", + "This is: 9\n", + "This is: 19\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for i,j in zip(range(10),range(10,20)):\n", + " print(\"This is: \" + str(i))\n", + " print(\"This is: \" + str(j))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1035\n", + "46\n" + ] + } + ], + "source": [ + "#One common usage of while loops is an external counter\n", + "#Can you figure out what the cell below is doing?\n", + "counter = 0\n", + "run_sum = 0\n", + "while run_sum<1000:\n", + " run_sum = run_sum + counter\n", + " counter = counter+1\n", + "print(run_sum)\n", + "print(counter)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Pandas'></a>\n", + "## Pandas\n", + "Pandas is **the** go-to library in Python for Data Analysis(for more about it's history, click [here](https://qz.com/1126615/the-story-of-the-most-important-tool-in-data-science/)). An excellent tool for the manipulation, organization, and processing of large datasets, Pandas is centered around the DataFrame object. \n", + "\n", + "In this section, I'm just going to manipulate this dataset and hopefully some of the code here will serve as an example of how to use the Panda's Library. We're going to be using a breast cancer dataset from Univ. of Wisconsin.\n", + "For more info and tutorials related to this dataset, clicke [here](https://www.kaggle.com/uciml/breast-cancer-wisconsin-data)\n", + "\n", + "\n", + "Side note: Kaggle is an excellent resource for tutorials and datasets. If you ever are looking for a big dataset to just play around with, Kaggle is the place to go. This method of just finding interesting data and looking for cool stuff to do with it is really how I learned Python, as well as all of these packages in this tutorial.\n", + "\n", + "Quick Resource: Check out Panda's 10minute tutorial [here](https://pandas.pydata.org/pandas-docs/stable/10min.html)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Always start off by importing the package\n", + "import pandas as pd\n", + "#Reading in the csv and converting it to a DataFrame, the extra part at the end just selects the first 32 columns\n", + "df = pd.read_csv(\"https://raw.githubusercontent.com/charlesxjyang/ML-tutorials/master/Python%20Tutorial/WisconsinBreastCancerDataset.csv\",usecols=list(range(32)))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>id</th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " <th>area_mean</th>\n", + " <th>smoothness_mean</th>\n", + " <th>compactness_mean</th>\n", + " <th>concavity_mean</th>\n", + " <th>concave points_mean</th>\n", + " <th>...</th>\n", + " <th>radius_worst</th>\n", + " <th>texture_worst</th>\n", + " <th>perimeter_worst</th>\n", + " <th>area_worst</th>\n", + " <th>smoothness_worst</th>\n", + " <th>compactness_worst</th>\n", + " <th>concavity_worst</th>\n", + " <th>concave points_worst</th>\n", + " <th>symmetry_worst</th>\n", + " <th>fractal_dimension_worst</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>842302</td>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.80</td>\n", + " <td>1001.0</td>\n", + " <td>0.11840</td>\n", + " <td>0.27760</td>\n", + " <td>0.3001</td>\n", + " <td>0.14710</td>\n", + " <td>...</td>\n", + " <td>25.38</td>\n", + " <td>17.33</td>\n", + " <td>184.60</td>\n", + " <td>2019.0</td>\n", + " <td>0.1622</td>\n", + " <td>0.6656</td>\n", + " <td>0.7119</td>\n", + " <td>0.2654</td>\n", + " <td>0.4601</td>\n", + " <td>0.11890</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>842517</td>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.90</td>\n", + " <td>1326.0</td>\n", + " <td>0.08474</td>\n", + " <td>0.07864</td>\n", + " <td>0.0869</td>\n", + " <td>0.07017</td>\n", + " <td>...</td>\n", + " <td>24.99</td>\n", + " <td>23.41</td>\n", + " <td>158.80</td>\n", + " <td>1956.0</td>\n", + " <td>0.1238</td>\n", + " <td>0.1866</td>\n", + " <td>0.2416</td>\n", + " <td>0.1860</td>\n", + " <td>0.2750</td>\n", + " <td>0.08902</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>84300903</td>\n", + " <td>M</td>\n", + " <td>19.69</td>\n", + " <td>21.25</td>\n", + " <td>130.00</td>\n", + " <td>1203.0</td>\n", + " <td>0.10960</td>\n", + " <td>0.15990</td>\n", + " <td>0.1974</td>\n", + " <td>0.12790</td>\n", + " <td>...</td>\n", + " <td>23.57</td>\n", + " <td>25.53</td>\n", + " <td>152.50</td>\n", + " <td>1709.0</td>\n", + " <td>0.1444</td>\n", + " <td>0.4245</td>\n", + " <td>0.4504</td>\n", + " <td>0.2430</td>\n", + " <td>0.3613</td>\n", + " <td>0.08758</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>84348301</td>\n", + " <td>M</td>\n", + " <td>11.42</td>\n", + " <td>20.38</td>\n", + " <td>77.58</td>\n", + " <td>386.1</td>\n", + " <td>0.14250</td>\n", + " <td>0.28390</td>\n", + " <td>0.2414</td>\n", + " <td>0.10520</td>\n", + " <td>...</td>\n", + " <td>14.91</td>\n", + " <td>26.50</td>\n", + " <td>98.87</td>\n", + " <td>567.7</td>\n", + " <td>0.2098</td>\n", + " <td>0.8663</td>\n", + " <td>0.6869</td>\n", + " <td>0.2575</td>\n", + " <td>0.6638</td>\n", + " <td>0.17300</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>84358402</td>\n", + " <td>M</td>\n", + " <td>20.29</td>\n", + " <td>14.34</td>\n", + " <td>135.10</td>\n", + " <td>1297.0</td>\n", + " <td>0.10030</td>\n", + " <td>0.13280</td>\n", + " <td>0.1980</td>\n", + " <td>0.10430</td>\n", + " <td>...</td>\n", + " <td>22.54</td>\n", + " <td>16.67</td>\n", + " <td>152.20</td>\n", + " <td>1575.0</td>\n", + " <td>0.1374</td>\n", + " <td>0.2050</td>\n", + " <td>0.4000</td>\n", + " <td>0.1625</td>\n", + " <td>0.2364</td>\n", + " <td>0.07678</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 32 columns</p>\n", + "</div>" + ], + "text/plain": [ + " id diagnosis radius_mean texture_mean perimeter_mean area_mean \\\n", + "0 842302 M 17.99 10.38 122.80 1001.0 \n", + "1 842517 M 20.57 17.77 132.90 1326.0 \n", + "2 84300903 M 19.69 21.25 130.00 1203.0 \n", + "3 84348301 M 11.42 20.38 77.58 386.1 \n", + "4 84358402 M 20.29 14.34 135.10 1297.0 \n", + "\n", + " smoothness_mean compactness_mean concavity_mean concave points_mean \\\n", + "0 0.11840 0.27760 0.3001 0.14710 \n", + "1 0.08474 0.07864 0.0869 0.07017 \n", + "2 0.10960 0.15990 0.1974 0.12790 \n", + "3 0.14250 0.28390 0.2414 0.10520 \n", + "4 0.10030 0.13280 0.1980 0.10430 \n", + "\n", + " ... radius_worst texture_worst perimeter_worst \\\n", + "0 ... 25.38 17.33 184.60 \n", + "1 ... 24.99 23.41 158.80 \n", + "2 ... 23.57 25.53 152.50 \n", + "3 ... 14.91 26.50 98.87 \n", + "4 ... 22.54 16.67 152.20 \n", + "\n", + " area_worst smoothness_worst compactness_worst concavity_worst \\\n", + "0 2019.0 0.1622 0.6656 0.7119 \n", + "1 1956.0 0.1238 0.1866 0.2416 \n", + "2 1709.0 0.1444 0.4245 0.4504 \n", + "3 567.7 0.2098 0.8663 0.6869 \n", + "4 1575.0 0.1374 0.2050 0.4000 \n", + "\n", + " concave points_worst symmetry_worst fractal_dimension_worst \n", + "0 0.2654 0.4601 0.11890 \n", + "1 0.1860 0.2750 0.08902 \n", + "2 0.2430 0.3613 0.08758 \n", + "3 0.2575 0.6638 0.17300 \n", + "4 0.1625 0.2364 0.07678 \n", + "\n", + "[5 rows x 32 columns]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#This just shows the first 5 rows, we will use this method to limit what is printed and save space\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the far left, you will note an unlabeled column of 0,1,2,3,4... \n", + "This is the \"index\" of the DataFrame and is how we reference each row. By default, it is just set to the integer index of the row. However, in some contexts, it makes more sense to assign it a different value e.g. a name. In our case, let's set the index to the patient id." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>id</th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " <th>area_mean</th>\n", + " <th>smoothness_mean</th>\n", + " <th>compactness_mean</th>\n", + " <th>concavity_mean</th>\n", + " <th>concave points_mean</th>\n", + " <th>...</th>\n", + " <th>radius_worst</th>\n", + " <th>texture_worst</th>\n", + " <th>perimeter_worst</th>\n", + " <th>area_worst</th>\n", + " <th>smoothness_worst</th>\n", + " <th>compactness_worst</th>\n", + " <th>concavity_worst</th>\n", + " <th>concave points_worst</th>\n", + " <th>symmetry_worst</th>\n", + " <th>fractal_dimension_worst</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>842302</td>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.80</td>\n", + " <td>1001.0</td>\n", + " <td>0.11840</td>\n", + " <td>0.27760</td>\n", + " <td>0.3001</td>\n", + " <td>0.14710</td>\n", + " <td>...</td>\n", + " <td>25.38</td>\n", + " <td>17.33</td>\n", + " <td>184.60</td>\n", + " <td>2019.0</td>\n", + " <td>0.1622</td>\n", + " <td>0.6656</td>\n", + " <td>0.7119</td>\n", + " <td>0.2654</td>\n", + " <td>0.4601</td>\n", + " <td>0.11890</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>842517</td>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.90</td>\n", + " <td>1326.0</td>\n", + " <td>0.08474</td>\n", + " <td>0.07864</td>\n", + " <td>0.0869</td>\n", + " <td>0.07017</td>\n", + " <td>...</td>\n", + " <td>24.99</td>\n", + " <td>23.41</td>\n", + " <td>158.80</td>\n", + " <td>1956.0</td>\n", + " <td>0.1238</td>\n", + " <td>0.1866</td>\n", + " <td>0.2416</td>\n", + " <td>0.1860</td>\n", + " <td>0.2750</td>\n", + " <td>0.08902</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>84300903</td>\n", + " <td>M</td>\n", + " <td>19.69</td>\n", + " <td>21.25</td>\n", + " <td>130.00</td>\n", + " <td>1203.0</td>\n", + " <td>0.10960</td>\n", + " <td>0.15990</td>\n", + " <td>0.1974</td>\n", + " <td>0.12790</td>\n", + " <td>...</td>\n", + " <td>23.57</td>\n", + " <td>25.53</td>\n", + " <td>152.50</td>\n", + " <td>1709.0</td>\n", + " <td>0.1444</td>\n", + " <td>0.4245</td>\n", + " <td>0.4504</td>\n", + " <td>0.2430</td>\n", + " <td>0.3613</td>\n", + " <td>0.08758</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>84348301</td>\n", + " <td>M</td>\n", + " <td>11.42</td>\n", + " <td>20.38</td>\n", + " <td>77.58</td>\n", + " <td>386.1</td>\n", + " <td>0.14250</td>\n", + " <td>0.28390</td>\n", + " <td>0.2414</td>\n", + " <td>0.10520</td>\n", + " <td>...</td>\n", + " <td>14.91</td>\n", + " <td>26.50</td>\n", + " <td>98.87</td>\n", + " <td>567.7</td>\n", + " <td>0.2098</td>\n", + " <td>0.8663</td>\n", + " <td>0.6869</td>\n", + " <td>0.2575</td>\n", + " <td>0.6638</td>\n", + " <td>0.17300</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>84358402</td>\n", + " <td>M</td>\n", + " <td>20.29</td>\n", + " <td>14.34</td>\n", + " <td>135.10</td>\n", + " <td>1297.0</td>\n", + " <td>0.10030</td>\n", + " <td>0.13280</td>\n", + " <td>0.1980</td>\n", + " <td>0.10430</td>\n", + " <td>...</td>\n", + " <td>22.54</td>\n", + " <td>16.67</td>\n", + " <td>152.20</td>\n", + " <td>1575.0</td>\n", + " <td>0.1374</td>\n", + " <td>0.2050</td>\n", + " <td>0.4000</td>\n", + " <td>0.1625</td>\n", + " <td>0.2364</td>\n", + " <td>0.07678</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 32 columns</p>\n", + "</div>" + ], + "text/plain": [ + " id diagnosis radius_mean texture_mean perimeter_mean area_mean \\\n", + "0 842302 M 17.99 10.38 122.80 1001.0 \n", + "1 842517 M 20.57 17.77 132.90 1326.0 \n", + "2 84300903 M 19.69 21.25 130.00 1203.0 \n", + "3 84348301 M 11.42 20.38 77.58 386.1 \n", + "4 84358402 M 20.29 14.34 135.10 1297.0 \n", + "\n", + " smoothness_mean compactness_mean concavity_mean concave points_mean \\\n", + "0 0.11840 0.27760 0.3001 0.14710 \n", + "1 0.08474 0.07864 0.0869 0.07017 \n", + "2 0.10960 0.15990 0.1974 0.12790 \n", + "3 0.14250 0.28390 0.2414 0.10520 \n", + "4 0.10030 0.13280 0.1980 0.10430 \n", + "\n", + " ... radius_worst texture_worst perimeter_worst \\\n", + "0 ... 25.38 17.33 184.60 \n", + "1 ... 24.99 23.41 158.80 \n", + "2 ... 23.57 25.53 152.50 \n", + "3 ... 14.91 26.50 98.87 \n", + "4 ... 22.54 16.67 152.20 \n", + "\n", + " area_worst smoothness_worst compactness_worst concavity_worst \\\n", + "0 2019.0 0.1622 0.6656 0.7119 \n", + "1 1956.0 0.1238 0.1866 0.2416 \n", + "2 1709.0 0.1444 0.4245 0.4504 \n", + "3 567.7 0.2098 0.8663 0.6869 \n", + "4 1575.0 0.1374 0.2050 0.4000 \n", + "\n", + " concave points_worst symmetry_worst fractal_dimension_worst \n", + "0 0.2654 0.4601 0.11890 \n", + "1 0.1860 0.2750 0.08902 \n", + "2 0.2430 0.3613 0.08758 \n", + "3 0.2575 0.6638 0.17300 \n", + "4 0.1625 0.2364 0.07678 \n", + "\n", + "[5 rows x 32 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.set_index('id')\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Huh, it seems nothing has changed. Why could that be?\n", + "\n", + "One good source to use troubleshooting, in addition to Google/StackOverFlow, is actual documentation, an important skill in general. Let's take a look at the [Panda's documentation for the set_index method](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.set_index.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nMYbxr8gGuMGcq8rOykRERERExVle2tFsA1NxUWwDXLPz4cwODypERERE55ei0sZlO5SKk4gIcP3h\nkIaCwwMdERERna/YuUJUdEV0gBsMA+CCxQMjERERFXfnS3uR7TaKFOd1gBsqBsRERFZsEBFRUcV2\nW2A8flOkYoBbTPAgTUR07rAhSHTuna9tIR5/iELDAJfyhAE3EZ3P2OAkKlxFsd3B4wBR0cQAlwoM\ng2AioqKNDfTiib+vhY/7ClHxwQCXiIjyjA1tIirKGJgSnX8Y4BIREQXBQJ6o6GDQSkSBMMAlIiIK\nAYNdonOLAS4RBcIAl4iI6DzFYL14Y6BHROSLAS4RERERERFFhH+of4mIiIiIiIiKNQa4RERERERE\nFBEY4BIREREREVFEYIBLREREREREEYEBLhEREREREUUEBrhEREREREQUERjgEhERERERUURggEtE\nREREREQRgQEuERERERERRQQGuERERERERBQRLjgrqPcRJTs7W72jSFWxYkX1zp2TJ0+qd0RERERE\nFA5lypRR74oG9uASERERERFRRGCAS0RERERERBGBAS4RERERERFFBAa4REREREREFBEY4BIRERER\nEVFEYIBLREREREREEYEBLlHWIozq1gudxCshRU2jADYhQZTVqPlZ6nNRl9f06t/rNHmT+pxf56rc\n7OvNYzrkfhK2shBSErR9Tn+NwOICL5ZzVf55lYXFT+el/qnvPb0I4XlYXl7TEYA65hafbUFERMUJ\nA1wiCk3WfuwV/9SoVln/XNTlNb3qey2rX65/zq9zVW729eYlHTIgiU0AwlUWMmiatki9l2qjRkEX\ny7kq/zw7iPSteal/+vdQ+0qE9qRwf/KaDv9SZycgqUEshnYpLtuCiIiKEwa4RBSS7PUrkYT6qH6F\nmlDE5Tm9B/Zp32tzbXga4eeq3HzWW/lWvPjNl4htrj67EeayQFYyEmXQNDAeC0VaFn4Ti4bqTwWl\nuNVbpKzDbPFPXk/M9GzdVP+cX3lNhz9ZizB9oUjfPbeGKQAnIiKyYoBL5EgNy9OGTyYgVU3VWIZW\nipd5KGCg4c6Of1PDYC0v2/oCUWlxM7Q6e/4I63qchjAGypuSmZ4m/m/qcVP5sqchdbJchjcv+vr1\noaj63/SX8T1L+uzr1dLl+103wyZ90ivZ8+lQ5tn7dor/y++Zt5GfbWNfnkO6HNPhxMU20MpAm+5N\n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\nUKfLA7irSXl9oj/29YeUTrGtckS9XyDrwkYcvVLUl7uqYcn637z7oJv85CTjo9HTsPmqe/HyQ9Ge\nkzWl6zTAxWu/xbRVv6NpTEtUYYxLRORKUQtwLzgrqPcRJTs76L0lqZirWDG026ucPHlSvSMiIiIi\nonAoU8Z0k8oiwM8gMyIiIiIiIqLihQEuERERERERRQQGuERERERERBQRGOASERERERFRRGCAS0RE\nRERERBGBAS4RERERERFFBAa4REREREREFBEY4BIREREREVFEYIBLREREREREEYEBLhEREREREUUE\nBrhEREREREQUERjgEhERERERUURggEtEREREREQRgQEuERERERERRQQGuERERERERBQRGOASERER\nERFRRGCAS0RERERERBGBAS4RERERERFFBAa4REREREREFBEY4BKdZ1In90KnbuL19CJkq2n5twkJ\ncpmTN6nPhUVf76j5WepzcZWPfKQk6NtTe43A4rAXhUPashZhlIttnT1/hCltDq+Q60ukbG8iIiIq\nKAxwiSj/svZjr/inZfXL9c+FRa23RrXK+ufiKs/5yMLiaYvUe6k2aoS7KOxpk8FtbAIQdFtnYf2K\nNPXeWcj1JVK2NxERERUYBrhElH8H9iEJ9dHm2sINPLLXr9TWW/0KNaGYynM+spKRuFUEigPjsfCb\nL8UrFg3Vn8LFJ22ut/VBpIu0oUEsPtfS5vt6sUto9SVStjcREREVHAa4RIpn6K7plZCi/ijJnivP\n9Cwsfto8bwJS1WyaUOY1WIaaipfPEGLTcuTQTtv8jsM2bfNY8uOG+n6w72Xv2yn+L3sP1VBl7ZXX\nfCou5stMlz2Etl5L+/f8DYO1z+eUXm0efdivpX7kYyi2ZdiuylPo+VB1ITZBBHxA0pQ4MY8p/W7y\npuqofdvq+fTOb06b9rdRssc4DZNixftA5WD06t8YjYr6lMBcpNm3nOz7lrv9ID/bj4iIiIo2BrhE\ngmy4P7FQfTCZPco5uJs9Kg6TZO+UxyI84ef6RzfzakGPFjiYbE3A3U6BibRwjM/8MsgxN+6dlinz\n45RPf/TANViPmRqK2mAnpncbg9lqqpZPW1DqDZBMZD7zNF8W9srkdfq3p9fS8XuyrGwBjWN5a9vF\nWt6pa8Q8DYBEEcxZyk0sM+STBYJM391TZJCmaHlKQKLMR4NqqKJPdZEP1Ttqpr7vNm96b+itaNNc\n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\n1eN3yiNsQBLeeKYXIs7sRPIi8Tu1aBXSf4rE5FeWIC7Swc3H8nBclhXIp9MyN+YbUB8nNslzIwUf\nXi9+pyf2VTMQUTC55hdBvQ8qRUVlj6xKNVtYWBnVPhY///yzekdXQsGmqRizojnm/X0COlTiRTFV\nP0VbEjHyTWByivcjX6hsLD8iIqrObrjhBvWuemANLhEFUDEyX4zF+Dmyf7DJ5ULkfHIKaN0MjRnc\nEhEREVElYYBLRAEk+z9G4tz+FDz34jq9T+qubUiRfZ2O3YSho3pe8VFEiYiIiCh4McAlooAKjU7E\nWzMHIOLMNiyeo/f12n99Lzz7yhLElzpaLhERERFRxbAPLtVY7INLRERERHRlsQ8uERERERERUSVg\ngEtERERERERBgQEuERERERERBQUGuERERERERBQUGOASERERERFRUGCAS0REREREREGBAS4RERER\nEREFBQa4REREREREFBQY4BIREREREVFQYIBLREREREREQeGaXwT1noiIiIiIiKjGYg0uERERERER\nBQUGuERERERERBQUGOASERERERFRUGCAS0REREREREGBAS4REREREREFBQa4REREREREFBQY4BIR\nEREREVFQYIBLREREREREQYEBLhEREREREQUFBrhEREREREQUFBjgEhERERERUVC45hdBvQ8qRUVF\n6h0Fq7CwMPWOiIiIiIiINbhEREREREQUJBjgEhERERERUVBggEtERERERERBgQEuERERERERBQUG\nuERERERERBQUGOASERERERFRULgKHxP0HXbMmIylx9VHO60ex8q596O8D6Ep2voCxnwSVaF1UNmq\n4jFBXyx5AAlp4k3bBPz9tYG4WZ/s2IX3nsZDO6PLtSxQgP956gksOKI+Co/Ofx8JndWHq4RWhktN\nheDSFs/+7WX8NkJ9LI+CLZj2diPMn9RBTXDOd7qUQX/Cx+VYLxERERGVH2tw7Rx/C2MeeQvH1Ed/\nHFs+CmP++qX6RFczGRyXGgCV4cJ7Cz2CWxnQNblNvb2KnP3KVxkewYLHHsC09wrUZz/J4PaxZKBJ\nfTXBHwXYu7P0fdutXOslIiIioopggOvTB3hn63fqPdGVNBDJO97HxzsqWFtZI+XgY6MGXSsD0+tv\nCegmvtq3dCH+pzwx7jdfYx/aole38hTqOWhxt1261Gv+g1fdziIiIiK64q7uJsr9EvHeuDv0yS5f\n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\nBjyignU5yJS+PfM2Sx3A6qrjHiDJ3K/Urg+rO7g7ggWP+Z5PctV0Gv0gRVDhz/L+qsx1e4gYiNHa\nKL7644O0gOk+47m9dv1NzVQgXGaApYI7uz6k4qXnayCSzQMoGY8McqVJvtxNgV01nqoPrT6fuqHh\ndFkfQact25pWwc90WptC2zZ79tpWB/SW+8hSflq5yRp+y+BWRERERMGCAa7VnY+7H/WzPcnVVLn1\nuDV4zxX8GmSTZc+Rh92BpXL6WxRZmkDr5ON7PPvHBpblsUUm8vFC5lGUST22Zv5A9UknH4GjP47F\nRI5+a5lPNgN1PdInLdNVA3zzg6NdNcOaE2dwwY/l/VaZ67a4Y9L7XuWlN1kuq2l06bWaLipg80Vv\nemttCt0BCdZH5chgTk1z1ZiaRoZ2N+l1uKxKV5npF+z7z0rOtqWPVu09EJa1ybRkty25j1z7XtEe\n6+T1uCkiIiKi4HHNL4J6H1SKitjDNNiFhZU6jjQREREREV1lWINLREREREREQYEBLhEREREREQUF\nBrhEREREREQUFBjgEhERERERUVBggEtERERERERBgQEuERERERERBQUGuERERERERBQUGOASERER\nERFRULjmF0G9JyIiIiIiIqqxWINLREREREREQYEBLhEREREREQUFBrhEREREREQUFBjgEhERERER\nUVBggEtERERERERBgQEuERERERERBQUGuERERERERBQUGOASERERERFRUGCAS0REREREREGBAS4R\nEREREREFBQa4REREREREFBQY4BIREREREVFQYIBLREREREREQYEBLhEREREREQUFBrhEREREREQU\nFBjgEhERERERUVBggEtERERERERBgQEuERERERERBQUGuERERERERBQUGOASERERERFRUGCAS0RE\nREREREGBAS4REREREREFBQa4REREREREFBQY4BIREREREVFQYIBLREREREREQYEBLhEREREREQUF\nBrhEREREREQUFBjgEhERERERUVBggEtERERERERBgQEuERERERERBQUGuERERERERBQUGOASERER\nERFRUGCAS0REREREREGBAS4REREREREFBQa4REREREREFBQY4BIREREREVFQYIBLREREREREQYEB\nLhEREREREQUFBrhEREREREQUFBjgEhERERERUVBggEtERERERERBgQEuERERERERBQUGuERERERE\nRBQUGOASERERERFRUGCAS0REREREREGBAS4REREREREFBQa4REREREREFBQY4BIREREREVFQYIBL\nREREREREQYEBLhEREREREQUFBrhEREREREQUFBjgEhERERERUVBggEtERERERERBgQEuERERERER\nBQUGuERERERERBQUrvlFUO+rr4ItmPZYMvapj748Ov99JHRWH2oqU16DIj9ERERERERVhDW4RERE\nREREFBQY4BIREREREVFQqHFNlJ002/1iyQNISJPv2uLZv72M30aIt+ZmzoP+hI8ndZDvhBwk3/f/\n8Lb6pBuI5B0JuEN9uvDe03ho6RHxTk6Pwsem+btN/CvmPxhhmkcybVfwWP5vjbHa3NzaIy1CKXl1\n50tnbNvDgWT0nrZFfVCs2yAiIiIiIgpCQVmDe8ejCeimvTuCBW/niL8F+J+5RlApgsxSg1tpCxLu\nS8YX6pObnO45/76lT2DaU+bgVhLbFUGq7fLm4FZK+3/o/dQWXFAf7Yn0P+UZ3Epy272XyPwpdsGt\nJLdhno+IiIiIiCgI1bgA9+1pD6D3fTYvc5AYMRDTJrbV34vgLnnJRixQ8eej8801s6v1YLVtAv6+\n4318LF/zB2rfyWD04wPqrZmsDZXz/c0IokWgeeSIVtsqp//d2C7ycLpAvTUzbcs175FkrLfblnLh\nvYUq/bJm2JLOtNX4H7WdLz5Rwa3dNkzzERERERERBaOg7YN784NT8ayK7d5OU4GfCE7NTX5vfvBl\nPVh8bSBuVrWktjWgLiLAfFTV/kb8Br2MWFYElCPUem/uFu2qPf7qG+2NiVh+htyWziONn/iqYS3A\n3p0qOh802tXsGZ0fVssewa59lshVBMwPqRpbVx53uJtMExERERERBaMgHmQqAr+d4a5l9WyabFBB\nrVYL/ISrlte3FmhqFyS2bOQKWktnXT4CTVuqtyfO+GimfA5fGemSTY1dtdbu9O776pz21900W3DN\n+zRrbomIiIiI6KpQ4wJcoymw10urhfV0YV+Gqb+rd5PjL5aYglqjWa+riXINFDEQ873yIPsDy0DX\nrk8wERERERFR8AjiGtwcrPcY+En23zUHeQU4fUJ/J0cjtguQA8/aL9edBt+1wPXRxGgKbfT/tb6s\nNdOdE9zfufoKb8Hq91iVS0REREREwSt4BpmSL9NIwV8sMUY7lo/mcQd5CTajCe/b+ZlqHlyA/3mr\n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\nGkIAAAAASUVORK5CYII=\n", + "text/plain": [ + "<IPython.core.display.Image object>" + ] + }, + "execution_count": 14, + "metadata": { + "image/png": { + "height": 100, + "width": 500 + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import Image\n", + "Image(\"https://raw.githubusercontent.com/charlesxjyang/ML-tutorials/master/Python%20Tutorial/Screenshots/df.set_index.PNG\", width=500, height=100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's first look at the big picture takeaways\n", + "1. Beneath the text in the blue banner, conveniantly circled in red for you, is the signature DataFrame.set_index(). Notice the DataFrame is in smaller text. What this convention means is that variable to which the DataFrame object is assigned to should be passed in e.g. we didn't pass in the actual \"DataFrame.set_index()\" but rather the variable df which is assigned to a DataFrame object. Inside the parentheses are the defaults for all the parameters. The blue link titled source links to the actual implementation of this method, and below the method signature is a short description of the method\n", + "\n", + "2. The next grey box below that goes into more depth about each parameter. For instance, the value passed to drop should be a boolean value, whereas key refers to the columns we want to set as the index.\n", + "\n", + "3. We can also see what this method returns, specifically a DataFrame object.\n", + "\n", + "4. Finally, Panda's helpfully provides some examples of how to use this method. If you actually go to the documentation page(linked above), you will see there are actually much more examples. \n", + "\n", + "Try and go to the documentation yourself. Read over the description and the examples and try to figure out exactly what mistakes we made(there were several) before continuing." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first mistake is that we did not pass a True value to the inplace parameter. Inplace is a common parameter in Panda's methods and it can easily trip up beginners. What we can do is set the variable assigned to the current DataFrame to the returned DataFrame. An equivalent alternative is to simply set inplace to True. The next cell will demonstrate both methods" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " <th>area_mean</th>\n", + " <th>smoothness_mean</th>\n", + " <th>compactness_mean</th>\n", + " <th>concavity_mean</th>\n", + " <th>concave points_mean</th>\n", + " <th>symmetry_mean</th>\n", + " <th>...</th>\n", + " <th>radius_worst</th>\n", + " <th>texture_worst</th>\n", + " <th>perimeter_worst</th>\n", + " <th>area_worst</th>\n", + " <th>smoothness_worst</th>\n", + " <th>compactness_worst</th>\n", + " <th>concavity_worst</th>\n", + " <th>concave points_worst</th>\n", + " <th>symmetry_worst</th>\n", + " <th>fractal_dimension_worst</th>\n", + " </tr>\n", + " <tr>\n", + " <th>id</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>842302</th>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.80</td>\n", + " <td>1001.0</td>\n", + " <td>0.11840</td>\n", + " <td>0.27760</td>\n", + " <td>0.3001</td>\n", + " <td>0.14710</td>\n", + " <td>0.2419</td>\n", + " <td>...</td>\n", + " <td>25.38</td>\n", + " <td>17.33</td>\n", + " <td>184.60</td>\n", + " <td>2019.0</td>\n", + " <td>0.1622</td>\n", + " <td>0.6656</td>\n", + " <td>0.7119</td>\n", + " <td>0.2654</td>\n", + " <td>0.4601</td>\n", + " <td>0.11890</td>\n", + " </tr>\n", + " <tr>\n", + " <th>842517</th>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.90</td>\n", + " <td>1326.0</td>\n", + " <td>0.08474</td>\n", + " <td>0.07864</td>\n", + " <td>0.0869</td>\n", + " <td>0.07017</td>\n", + " <td>0.1812</td>\n", + " <td>...</td>\n", + " <td>24.99</td>\n", + " <td>23.41</td>\n", + " <td>158.80</td>\n", + " <td>1956.0</td>\n", + " <td>0.1238</td>\n", + " <td>0.1866</td>\n", + " <td>0.2416</td>\n", + " <td>0.1860</td>\n", + " <td>0.2750</td>\n", + " <td>0.08902</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84300903</th>\n", + " <td>M</td>\n", + " <td>19.69</td>\n", + " <td>21.25</td>\n", + " <td>130.00</td>\n", + " <td>1203.0</td>\n", + " <td>0.10960</td>\n", + " <td>0.15990</td>\n", + " <td>0.1974</td>\n", + " <td>0.12790</td>\n", + " <td>0.2069</td>\n", + " <td>...</td>\n", + " <td>23.57</td>\n", + " <td>25.53</td>\n", + " <td>152.50</td>\n", + " <td>1709.0</td>\n", + " <td>0.1444</td>\n", + " <td>0.4245</td>\n", + " <td>0.4504</td>\n", + " <td>0.2430</td>\n", + " <td>0.3613</td>\n", + " <td>0.08758</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84348301</th>\n", + " <td>M</td>\n", + " <td>11.42</td>\n", + " <td>20.38</td>\n", + " <td>77.58</td>\n", + " <td>386.1</td>\n", + " <td>0.14250</td>\n", + " <td>0.28390</td>\n", + " <td>0.2414</td>\n", + " <td>0.10520</td>\n", + " <td>0.2597</td>\n", + " <td>...</td>\n", + " <td>14.91</td>\n", + " <td>26.50</td>\n", + " <td>98.87</td>\n", + " <td>567.7</td>\n", + " <td>0.2098</td>\n", + " <td>0.8663</td>\n", + " <td>0.6869</td>\n", + " <td>0.2575</td>\n", + " <td>0.6638</td>\n", + " <td>0.17300</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84358402</th>\n", + " <td>M</td>\n", + " <td>20.29</td>\n", + " <td>14.34</td>\n", + " <td>135.10</td>\n", + " <td>1297.0</td>\n", + " <td>0.10030</td>\n", + " <td>0.13280</td>\n", + " <td>0.1980</td>\n", + " <td>0.10430</td>\n", + " <td>0.1809</td>\n", + " <td>...</td>\n", + " <td>22.54</td>\n", + " <td>16.67</td>\n", + " <td>152.20</td>\n", + " <td>1575.0</td>\n", + " <td>0.1374</td>\n", + " <td>0.2050</td>\n", + " <td>0.4000</td>\n", + " <td>0.1625</td>\n", + " <td>0.2364</td>\n", + " <td>0.07678</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 31 columns</p>\n", + "</div>" + ], + "text/plain": [ + " diagnosis radius_mean texture_mean perimeter_mean area_mean \\\n", + "id \n", + "842302 M 17.99 10.38 122.80 1001.0 \n", + "842517 M 20.57 17.77 132.90 1326.0 \n", + "84300903 M 19.69 21.25 130.00 1203.0 \n", + "84348301 M 11.42 20.38 77.58 386.1 \n", + "84358402 M 20.29 14.34 135.10 1297.0 \n", + "\n", + " smoothness_mean compactness_mean concavity_mean \\\n", + "id \n", + "842302 0.11840 0.27760 0.3001 \n", + "842517 0.08474 0.07864 0.0869 \n", + "84300903 0.10960 0.15990 0.1974 \n", + "84348301 0.14250 0.28390 0.2414 \n", + "84358402 0.10030 0.13280 0.1980 \n", + "\n", + " concave points_mean symmetry_mean ... \\\n", + "id ... \n", + "842302 0.14710 0.2419 ... \n", + "842517 0.07017 0.1812 ... \n", + "84300903 0.12790 0.2069 ... \n", + "84348301 0.10520 0.2597 ... \n", + "84358402 0.10430 0.1809 ... \n", + "\n", + " radius_worst texture_worst perimeter_worst area_worst \\\n", + "id \n", + "842302 25.38 17.33 184.60 2019.0 \n", + "842517 24.99 23.41 158.80 1956.0 \n", + "84300903 23.57 25.53 152.50 1709.0 \n", + "84348301 14.91 26.50 98.87 567.7 \n", + "84358402 22.54 16.67 152.20 1575.0 \n", + "\n", + " smoothness_worst compactness_worst concavity_worst \\\n", + "id \n", + "842302 0.1622 0.6656 0.7119 \n", + "842517 0.1238 0.1866 0.2416 \n", + "84300903 0.1444 0.4245 0.4504 \n", + "84348301 0.2098 0.8663 0.6869 \n", + "84358402 0.1374 0.2050 0.4000 \n", + "\n", + " concave points_worst symmetry_worst fractal_dimension_worst \n", + "id \n", + "842302 0.2654 0.4601 0.11890 \n", + "842517 0.1860 0.2750 0.08902 \n", + "84300903 0.2430 0.3613 0.08758 \n", + "84348301 0.2575 0.6638 0.17300 \n", + "84358402 0.1625 0.2364 0.07678 \n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Method 1 is to simply set the current DataFrame to the returned DataFrame. \n", + "#In our case, I will assign it to a different variable so I can also demonstrate the second method\n", + "test_df = df.set_index('id')\n", + "test_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " <th>area_mean</th>\n", + " <th>smoothness_mean</th>\n", + " <th>compactness_mean</th>\n", + " <th>concavity_mean</th>\n", + " <th>concave points_mean</th>\n", + " <th>symmetry_mean</th>\n", + " <th>...</th>\n", + " <th>radius_worst</th>\n", + " <th>texture_worst</th>\n", + " <th>perimeter_worst</th>\n", + " <th>area_worst</th>\n", + " <th>smoothness_worst</th>\n", + " <th>compactness_worst</th>\n", + " <th>concavity_worst</th>\n", + " <th>concave points_worst</th>\n", + " <th>symmetry_worst</th>\n", + " <th>fractal_dimension_worst</th>\n", + " </tr>\n", + " <tr>\n", + " <th>id</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>842302</th>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.80</td>\n", + " <td>1001.0</td>\n", + " <td>0.11840</td>\n", + " <td>0.27760</td>\n", + " <td>0.3001</td>\n", + " <td>0.14710</td>\n", + " <td>0.2419</td>\n", + " <td>...</td>\n", + " <td>25.38</td>\n", + " <td>17.33</td>\n", + " <td>184.60</td>\n", + " <td>2019.0</td>\n", + " <td>0.1622</td>\n", + " <td>0.6656</td>\n", + " <td>0.7119</td>\n", + " <td>0.2654</td>\n", + " <td>0.4601</td>\n", + " <td>0.11890</td>\n", + " </tr>\n", + " <tr>\n", + " <th>842517</th>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.90</td>\n", + " <td>1326.0</td>\n", + " <td>0.08474</td>\n", + " <td>0.07864</td>\n", + " <td>0.0869</td>\n", + " <td>0.07017</td>\n", + " <td>0.1812</td>\n", + " <td>...</td>\n", + " <td>24.99</td>\n", + " <td>23.41</td>\n", + " <td>158.80</td>\n", + " <td>1956.0</td>\n", + " <td>0.1238</td>\n", + " <td>0.1866</td>\n", + " <td>0.2416</td>\n", + " <td>0.1860</td>\n", + " <td>0.2750</td>\n", + " <td>0.08902</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84300903</th>\n", + " <td>M</td>\n", + " <td>19.69</td>\n", + " <td>21.25</td>\n", + " <td>130.00</td>\n", + " <td>1203.0</td>\n", + " <td>0.10960</td>\n", + " <td>0.15990</td>\n", + " <td>0.1974</td>\n", + " <td>0.12790</td>\n", + " <td>0.2069</td>\n", + " <td>...</td>\n", + " <td>23.57</td>\n", + " <td>25.53</td>\n", + " <td>152.50</td>\n", + " <td>1709.0</td>\n", + " <td>0.1444</td>\n", + " <td>0.4245</td>\n", + " <td>0.4504</td>\n", + " <td>0.2430</td>\n", + " <td>0.3613</td>\n", + " <td>0.08758</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84348301</th>\n", + " <td>M</td>\n", + " <td>11.42</td>\n", + " <td>20.38</td>\n", + " <td>77.58</td>\n", + " <td>386.1</td>\n", + " <td>0.14250</td>\n", + " <td>0.28390</td>\n", + " <td>0.2414</td>\n", + " <td>0.10520</td>\n", + " <td>0.2597</td>\n", + " <td>...</td>\n", + " <td>14.91</td>\n", + " <td>26.50</td>\n", + " <td>98.87</td>\n", + " <td>567.7</td>\n", + " <td>0.2098</td>\n", + " <td>0.8663</td>\n", + " <td>0.6869</td>\n", + " <td>0.2575</td>\n", + " <td>0.6638</td>\n", + " <td>0.17300</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84358402</th>\n", + " <td>M</td>\n", + " <td>20.29</td>\n", + " <td>14.34</td>\n", + " <td>135.10</td>\n", + " <td>1297.0</td>\n", + " <td>0.10030</td>\n", + " <td>0.13280</td>\n", + " <td>0.1980</td>\n", + " <td>0.10430</td>\n", + " <td>0.1809</td>\n", + " <td>...</td>\n", + " <td>22.54</td>\n", + " <td>16.67</td>\n", + " <td>152.20</td>\n", + " <td>1575.0</td>\n", + " <td>0.1374</td>\n", + " <td>0.2050</td>\n", + " <td>0.4000</td>\n", + " <td>0.1625</td>\n", + " <td>0.2364</td>\n", + " <td>0.07678</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 31 columns</p>\n", + "</div>" + ], + "text/plain": [ + " diagnosis radius_mean texture_mean perimeter_mean area_mean \\\n", + "id \n", + "842302 M 17.99 10.38 122.80 1001.0 \n", + "842517 M 20.57 17.77 132.90 1326.0 \n", + "84300903 M 19.69 21.25 130.00 1203.0 \n", + "84348301 M 11.42 20.38 77.58 386.1 \n", + "84358402 M 20.29 14.34 135.10 1297.0 \n", + "\n", + " smoothness_mean compactness_mean concavity_mean \\\n", + "id \n", + "842302 0.11840 0.27760 0.3001 \n", + "842517 0.08474 0.07864 0.0869 \n", + "84300903 0.10960 0.15990 0.1974 \n", + "84348301 0.14250 0.28390 0.2414 \n", + "84358402 0.10030 0.13280 0.1980 \n", + "\n", + " concave points_mean symmetry_mean ... \\\n", + "id ... \n", + "842302 0.14710 0.2419 ... \n", + "842517 0.07017 0.1812 ... \n", + "84300903 0.12790 0.2069 ... \n", + "84348301 0.10520 0.2597 ... \n", + "84358402 0.10430 0.1809 ... \n", + "\n", + " radius_worst texture_worst perimeter_worst area_worst \\\n", + "id \n", + "842302 25.38 17.33 184.60 2019.0 \n", + "842517 24.99 23.41 158.80 1956.0 \n", + "84300903 23.57 25.53 152.50 1709.0 \n", + "84348301 14.91 26.50 98.87 567.7 \n", + "84358402 22.54 16.67 152.20 1575.0 \n", + "\n", + " smoothness_worst compactness_worst concavity_worst \\\n", + "id \n", + "842302 0.1622 0.6656 0.7119 \n", + "842517 0.1238 0.1866 0.2416 \n", + "84300903 0.1444 0.4245 0.4504 \n", + "84348301 0.2098 0.8663 0.6869 \n", + "84358402 0.1374 0.2050 0.4000 \n", + "\n", + " concave points_worst symmetry_worst fractal_dimension_worst \n", + "id \n", + "842302 0.2654 0.4601 0.11890 \n", + "842517 0.1860 0.2750 0.08902 \n", + "84300903 0.2430 0.3613 0.08758 \n", + "84348301 0.2575 0.6638 0.17300 \n", + "84358402 0.1625 0.2364 0.07678 \n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Method 2 is to set inplace to True.\n", + "df.set_index('id',inplace=True)\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>id</th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " <th>area_mean</th>\n", + " <th>smoothness_mean</th>\n", + " <th>compactness_mean</th>\n", + " <th>concavity_mean</th>\n", + " <th>concave points_mean</th>\n", + " <th>...</th>\n", + " <th>radius_worst</th>\n", + " <th>texture_worst</th>\n", + " <th>perimeter_worst</th>\n", + " <th>area_worst</th>\n", + " <th>smoothness_worst</th>\n", + " <th>compactness_worst</th>\n", + " <th>concavity_worst</th>\n", + " <th>concave points_worst</th>\n", + " <th>symmetry_worst</th>\n", + " <th>fractal_dimension_worst</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>842302</td>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.80</td>\n", + " <td>1001.0</td>\n", + " <td>0.11840</td>\n", + " <td>0.27760</td>\n", + " <td>0.3001</td>\n", + " <td>0.14710</td>\n", + " <td>...</td>\n", + " <td>25.38</td>\n", + " <td>17.33</td>\n", + " <td>184.60</td>\n", + " <td>2019.0</td>\n", + " <td>0.1622</td>\n", + " <td>0.6656</td>\n", + " <td>0.7119</td>\n", + " <td>0.2654</td>\n", + " <td>0.4601</td>\n", + " <td>0.11890</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>842517</td>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.90</td>\n", + " <td>1326.0</td>\n", + " <td>0.08474</td>\n", + " <td>0.07864</td>\n", + " <td>0.0869</td>\n", + " <td>0.07017</td>\n", + " <td>...</td>\n", + " <td>24.99</td>\n", + " <td>23.41</td>\n", + " <td>158.80</td>\n", + " <td>1956.0</td>\n", + " <td>0.1238</td>\n", + " <td>0.1866</td>\n", + " <td>0.2416</td>\n", + " <td>0.1860</td>\n", + " <td>0.2750</td>\n", + " <td>0.08902</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>84300903</td>\n", + " <td>M</td>\n", + " <td>19.69</td>\n", + " <td>21.25</td>\n", + " <td>130.00</td>\n", + " <td>1203.0</td>\n", + " <td>0.10960</td>\n", + " <td>0.15990</td>\n", + " <td>0.1974</td>\n", + " <td>0.12790</td>\n", + " <td>...</td>\n", + " <td>23.57</td>\n", + " <td>25.53</td>\n", + " <td>152.50</td>\n", + " <td>1709.0</td>\n", + " <td>0.1444</td>\n", + " <td>0.4245</td>\n", + " <td>0.4504</td>\n", + " <td>0.2430</td>\n", + " <td>0.3613</td>\n", + " <td>0.08758</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>84348301</td>\n", + " <td>M</td>\n", + " <td>11.42</td>\n", + " <td>20.38</td>\n", + " <td>77.58</td>\n", + " <td>386.1</td>\n", + " <td>0.14250</td>\n", + " <td>0.28390</td>\n", + " <td>0.2414</td>\n", + " <td>0.10520</td>\n", + " <td>...</td>\n", + " <td>14.91</td>\n", + " <td>26.50</td>\n", + " <td>98.87</td>\n", + " <td>567.7</td>\n", + " <td>0.2098</td>\n", + " <td>0.8663</td>\n", + " <td>0.6869</td>\n", + " <td>0.2575</td>\n", + " <td>0.6638</td>\n", + " <td>0.17300</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>84358402</td>\n", + " <td>M</td>\n", + " <td>20.29</td>\n", + " <td>14.34</td>\n", + " <td>135.10</td>\n", + " <td>1297.0</td>\n", + " <td>0.10030</td>\n", + " <td>0.13280</td>\n", + " <td>0.1980</td>\n", + " <td>0.10430</td>\n", + " <td>...</td>\n", + " <td>22.54</td>\n", + " <td>16.67</td>\n", + " <td>152.20</td>\n", + " <td>1575.0</td>\n", + " <td>0.1374</td>\n", + " <td>0.2050</td>\n", + " <td>0.4000</td>\n", + " <td>0.1625</td>\n", + " <td>0.2364</td>\n", + " <td>0.07678</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 32 columns</p>\n", + "</div>" + ], + "text/plain": [ + " id diagnosis radius_mean texture_mean perimeter_mean area_mean \\\n", + "0 842302 M 17.99 10.38 122.80 1001.0 \n", + "1 842517 M 20.57 17.77 132.90 1326.0 \n", + "2 84300903 M 19.69 21.25 130.00 1203.0 \n", + "3 84348301 M 11.42 20.38 77.58 386.1 \n", + "4 84358402 M 20.29 14.34 135.10 1297.0 \n", + "\n", + " smoothness_mean compactness_mean concavity_mean concave points_mean \\\n", + "0 0.11840 0.27760 0.3001 0.14710 \n", + "1 0.08474 0.07864 0.0869 0.07017 \n", + "2 0.10960 0.15990 0.1974 0.12790 \n", + "3 0.14250 0.28390 0.2414 0.10520 \n", + "4 0.10030 0.13280 0.1980 0.10430 \n", + "\n", + " ... radius_worst texture_worst perimeter_worst \\\n", + "0 ... 25.38 17.33 184.60 \n", + "1 ... 24.99 23.41 158.80 \n", + "2 ... 23.57 25.53 152.50 \n", + "3 ... 14.91 26.50 98.87 \n", + "4 ... 22.54 16.67 152.20 \n", + "\n", + " area_worst smoothness_worst compactness_worst concavity_worst \\\n", + "0 2019.0 0.1622 0.6656 0.7119 \n", + "1 1956.0 0.1238 0.1866 0.2416 \n", + "2 1709.0 0.1444 0.4245 0.4504 \n", + "3 567.7 0.2098 0.8663 0.6869 \n", + "4 1575.0 0.1374 0.2050 0.4000 \n", + "\n", + " concave points_worst symmetry_worst fractal_dimension_worst \n", + "0 0.2654 0.4601 0.11890 \n", + "1 0.1860 0.2750 0.08902 \n", + "2 0.2430 0.3613 0.08758 \n", + "3 0.2575 0.6638 0.17300 \n", + "4 0.1625 0.2364 0.07678 \n", + "\n", + "[5 rows x 32 columns]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#A few more notes related to index: we can actually specify the index when we instantiate a DataFrame object(see documentation for more)\n", + "#to reset the index\n", + "df.reset_index().head()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([ 842302, 842517, 84300903, 84348301, 84358402, 843786,\n", + " 844359, 84458202, 844981, 84501001,\n", + " ...\n", + " 925291, 925292, 925311, 925622, 926125, 926424,\n", + " 926682, 926954, 927241, 92751],\n", + " dtype='int64', name='id', length=569)" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#If you ever want to access the index. Can manipulate like and convert to list, iterate over, etc.\n", + "df.index\n", + "#note that it is still 'id' that is index. This is because we did not use inplace=True or assign df to the object\n", + "#returned by reset_index()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This brief detour hopefully gave a quick lesson on how to read documentation effectively. The next few examples will go by much quicker now." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " </tr>\n", + " <tr>\n", + " <th>id</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>842302</th>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.80</td>\n", + " </tr>\n", + " <tr>\n", + " <th>842517</th>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.90</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84300903</th>\n", + " <td>M</td>\n", + " <td>19.69</td>\n", + " <td>21.25</td>\n", + " <td>130.00</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84348301</th>\n", + " <td>M</td>\n", + " <td>11.42</td>\n", + " <td>20.38</td>\n", + " <td>77.58</td>\n", + " </tr>\n", + " <tr>\n", + " <th>84358402</th>\n", + " <td>M</td>\n", + " <td>20.29</td>\n", + " <td>14.34</td>\n", + " <td>135.10</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " diagnosis radius_mean texture_mean perimeter_mean\n", + "id \n", + "842302 M 17.99 10.38 122.80\n", + "842517 M 20.57 17.77 132.90\n", + "84300903 M 19.69 21.25 130.00\n", + "84348301 M 11.42 20.38 77.58\n", + "84358402 M 20.29 14.34 135.10" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Indexing\n", + "#Finding the first 4 columns\n", + "columns = ['diagnosis','radius_mean','texture_mean','perimeter_mean']\n", + "df[columns].head()\n", + "#notice how we chain together the first operation, which uses [] notation to select some subset of the columns\n", + "#and then use the head() method on the subset of the df returned by df[columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " </tr>\n", + " <tr>\n", + " <th>id</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>842302</th>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.8</td>\n", + " </tr>\n", + " <tr>\n", + " <th>842517</th>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.9</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " diagnosis radius_mean texture_mean perimeter_mean\n", + "id \n", + "842302 M 17.99 10.38 122.8\n", + "842517 M 20.57 17.77 132.9" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Indexing 2 \n", + "#finding the first 2 rows and 4 columns, via loc, which is based on actual column name/index label\n", + "columns = ['diagnosis','radius_mean','texture_mean','perimeter_mean']\n", + "rows = [842302,842517]\n", + "df.loc[rows,columns]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style>\n", + " .dataframe thead tr:only-child th {\n", + " text-align: right;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: left;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>diagnosis</th>\n", + " <th>radius_mean</th>\n", + " <th>texture_mean</th>\n", + " <th>perimeter_mean</th>\n", + " </tr>\n", + " <tr>\n", + " <th>id</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>842302</th>\n", + " <td>M</td>\n", + " <td>17.99</td>\n", + " <td>10.38</td>\n", + " <td>122.8</td>\n", + " </tr>\n", + " <tr>\n", + " <th>842517</th>\n", + " <td>M</td>\n", + " <td>20.57</td>\n", + " <td>17.77</td>\n", + " <td>132.9</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " diagnosis radius_mean texture_mean perimeter_mean\n", + "id \n", + "842302 M 17.99 10.38 122.8\n", + "842517 M 20.57 17.77 132.9" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#finding the first 2 rows and first 4 columns, via iloc, which only takes the integer index\n", + "df.iloc[:2,:4]" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (<ipython-input-22-0095974044f1>, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"<ipython-input-22-0095974044f1>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m Suppose we\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "#dropping things\n", + "Suppose we " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#boolean masks\n", + "#select all rows with malignant diagnoses, denoted by M\n", + "df[df['diagnosis']=='M'].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#selecting all rows with perimeter_mean less than 100\n", + "df[df['perimeter_mean']<100].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#selecting all rows with perimeter_mean less than 100 and malignant diagnosis\n", + "df[(df['diagnosis']=='M')&(df['perimeter_mean']<100)].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Some basic operations\n", + "#Finding the mean of compactness_mean\n", + "df['compactness_mean'].mean()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#finding mean, variance, sum of a subset of columns\n", + "cols = ['perimeter_mean','area_mean','smoothness_mean']\n", + "\n", + "print(\"This is the Mean:\\n{0}\".format(df[cols].mean()))\n", + "print('\\n')\n", + "print(\"This is the Variance:\\n{0}\".format(df[cols].var()))\n", + "print('\\n')\n", + "print(\"This is the sum:\\n{0}\".format(df[cols].sum()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Applying these operations by row\n", + "df[cols].mean(axis=1).head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Finding data distributions\n", + "num_malignant = sum(df['diagnosis']=='M') #returns an array of booleans. By default, True==1, False==0, so sum counts num_True\n", + "total_num_diagnoses = len(df)\n", + "print(\"The Percentage of Malignant Diganoses in this dataset is: {:0.04}%\".format((num_malignant/total_num_diagnoses)*100))\n", + "print(\"The Percentage of Benign Diganoses in this dataset is: {:0.04}%\".format((1-(num_malignant/total_num_diagnoses))*100))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A note about the axis parameter:\n", + "For many operations in panda's, there is the axis parameter that denotes if the operation is to be applied across rows or columns. For instance, as we saw above, do we want the mean value of the columms or of the rows? Axis can be {0,1}, with a mapping to row or column and is a handy tool to understand." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#merging/concatenating??" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#a note about groupby" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# a note about copies, inplace??" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#dealing with nan" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Matplotlib'></a>\n", + "## Matplotlib\n", + "Matplotlib is the most common plotting library used in Python. (Based off of Matlab's intuitive design)[https://matplotlib.org/users/history.html], matplotlib is designed to provide a simple graphics interface for Python users. That said, it is quite complicated, so we'll only provide a few brief tutorials. Personally, I don't actually have a solid understanding of Matplotlib's object system, just a hazy overview. That basic knowledge, in conjunction with significant experience using StackOverFlow, Github, and Google, has gotten me through so far. Lesson: Don't underestimate the power of the internet.\n", + "\n", + "We will be making various independent plots using the Pandas skills we have learned above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Let's plot the distribution of the radius mean\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "figure,ax = plt.subplots()\n", + "ax.hist(df['radius_mean'])\n", + "ax.set_title(\"Distribution of Mean Radius of Tumor\")\n", + "ax.set_xlabel(\"Radius Mean\")\n", + "ax.set_ylabel(\"Count\")\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Let's plot that same data but with a stacked bar plot, normalized by count\n", + "malignant = df[df['diagnosis']=='M'].loc[:,'concave points_mean']\n", + "benign = df[df['diagnosis']=='B'].loc[:,'concave points_mean']\n", + "\n", + "fig,ax = plt.subplots()\n", + "ax.bar(malignant,label='Malignant')\n", + "ax.bar(benign,bottom=malignant,label='Benign')\n", + "ax.set_title(\"Distribution of Mean of Concave Points of Tumor\")\n", + "ax.set_xlabel(\"Concave Points Mean\")\n", + "ax.set_ylabel(\"Count\")\n", + "fig.legend(loc='right')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Let's plot multiple columns histogram broken up by malignant and benign tumor diagnoses\n", + "\n", + "#This function will take a list of columns and a tuple describing how the subplots will be laid out in (num_row,num_col) format. \n", + "#Try playing around with various figshapes and seeing what happens!\n", + "def col_hist_plotter(df,columns,figshape):\n", + " fix,axes = plt.subplots(figshape[0],figshape[1],figsize=(15,10))\n", + " for ax,col in zip(axes.flatten(),columns):\n", + " malignant = df[df['diagnosis']=='M'].loc[:,col]\n", + " benign = df[df['diagnosis']=='B'].loc[:,col]\n", + " ax.hist(malignant,label='Malignant')\n", + " ax.hist(benign,label='Benign')\n", + " ax.set_title(\"Distribution of \"+col)\n", + " ax.set_xlabel(col)\n", + " ax.set_ylabel(\"Count\")\n", + " ax.legend()\n", + " plt.tight_layout()\n", + "col_hist_plotter(df,['concavity_mean','compactness_mean','texture_mean','area_mean'],(2,2))\n", + "#Note this code is not completely tested: should have an assertion that columns and figshape match up\n", + "#should have an automated method of adjusting figsize to figshape, in this case we just made the figsize really big" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Let's plot the average radius_worst for malignant and benign\n", + "avg_malignant = df[df['diagnosis']=='M'].loc[:,'radius_worst'].mean()\n", + "avg_benign = df[df['diagnosis']=='B'].loc[:,'radius_worst'].mean()\n", + "\n", + "fig,ax = plt.subplots()\n", + "ax.hist(malignant,label='Malignant')\n", + "ax.hist(benign,label='Benign')\n", + "ax.set_title(\"Distribution of Mean of Concave Points of Tumor\")\n", + "ax.set_xlabel(\"Concave Points Mean\")\n", + "ax.set_ylabel(\"Count\")\n", + "fig.legend(loc='right')\n", + "#This method is often the solution when your plots are too close or otherwise weirdly spaced\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#scatter plot, clustering?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#plotting, seaborn, boxplot, bar graph with errors, histogram with normal distribution fitting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Sklearn'></a>\n", + "## Scikit Learn\n", + "Scikit Learn is one of the most popular high-level API's for machine learning and data analysis in Python. Designed to be as succinct and clean as possible, the entire library revolves around the model object. In this section, I'm simply going to walk through \n", + "\n", + "confusion matrix plotter was adapted from [sklearn example](http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import train_test_split\n", + "#converts M,B to 1,0 respectively\n", + "y = np.array(df['diagnosis']=='M').astype(int)\n", + "\n", + "X_train,X_test,y_train,y_test = train_test_split(df.iloc[:,1:],df['diagnosis'])\n", + "\n", + "#instantiating the model object\n", + "model = LogisticRegression()\n", + "#fitting/training model on train data\n", + "model.fit(X_train,y_train)\n", + "#model will predict based on given X_test\n", + "y_pred = model.predict(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Adopted from sklearn confusion_matrix example\n", + "def plot_confusion_matrix(cm, classes):\n", + " cmap=plt.cm.Blues\n", + " cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n", + " print(\"Normalized confusion matrix\")\n", + " \n", + " plt.imshow(cm, interpolation='nearest', cmap=cmap)\n", + " plt.title('Confusion matrix')\n", + " plt.colorbar()\n", + " tick_marks = np.arange(len(classes))\n", + " plt.xticks(tick_marks, classes, rotation=45)\n", + " plt.yticks(tick_marks, classes)\n", + "\n", + " fmt = '.2f'\n", + " thresh = cm.max() / 2.\n", + " for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n", + " plt.text(j, i, format(cm[i, j], fmt),\n", + " horizontalalignment=\"center\",\n", + " color=\"white\" if cm[i, j] > thresh else \"black\")\n", + "\n", + " plt.tight_layout()\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label')\n", + "from sklearn.metrics import confusion_matrix\n", + "import itertools\n", + "cnf_matrix = confusion_matrix(y_test,y_pred)\n", + "class_names = ['Benign','Malignant']\n", + "plot_confusion_matrix(cnf_matrix,class_names)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#give a warning about the dangers of using models/metrics one doesn't understand\n", + "#use another more complex model to demonstrate the simplicity of the model object API" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Python'></a>\n", + "## Python as a Programming Language\n", + "#### Some brief notes about Python\n", + "IMHO, Python is really quite a beautiful langauge and is **the** best language to start out in, both for learning cs and for diving deep into data science. Elegantly simple it is quickly becoming [one of the most desirable programming languages in the field](https://insights.stackoverflow.com/survey/2017). In particular, Python has a robust library ecosystem, with most tech companies releasing packages in Python. In short, Python is much simpler to understand, has incredible support systems built in for optimization and modelling, and is syntactically succinct(unlike R).\n", + "\n", + "With that said, there are some downfalls to Python that you should be aware of. Now, none of these should dissuade you from learning Python. Hopefully I've made my love for this language clear above. But as one dives deeper into Data Science or programming in general, these shortcomings will become more important and one should be aware of them.\n", + "\n", + "1) Less intuitive Object Oriented Programming\n", + "This is not necessarily a bad thing. But OOP is not built into Python the way it is for, say java, where the language is designed around classes. Given the broad usage of this paradigm, it is important to understand and be experienced with Object orientation and sometimes Python allows you to slip into functional programming without ever touching classes.\n", + "\n", + "2) Poor memory management\n", + "This one is a biggie. Python's dynamic typing and relatively higher level of abstraction means that it is much harder to maintain fine control over memory. This is also a result of the fact that Python is interpreted rather than compiled.\n", + "\n", + "3) It's slow(relatively)\n", + "Speed tests reveal that Python can be orders of magnitude slower than other languages, like C/C++. But these orders of magnitude are relative - for the most part, the speed doesn't matter until operations become very computationally expensive or datasets are much larger.\n", + "\n", + "If you want to read more about the reasons for why Python's performance can be poorer compared to other languages, check out this [link](jakevdp.github.io/blog/2014/05/09/why-python-is-slow/)\n", + "\n", + "Still interested in learning more about programming languages? Take [CS164](https://inst.eecs.berkeley.edu/~cs164/archives.html) at Berkeley!\n", + "\n", + "#### Writing Pythonic (and just good) Code - a quick overview\n", + "1) Variables should be named in such a manner that their purpose and origin are easily identifiable\n", + "\n", + "2) Functions and methods should have clear documentation using ''' triple quotes describing the input parameters, output and the functions purpose\n", + "\n", + "3) Code should be written for other humans to read, not a computer\n", + "\n", + "4) I could talk about Pythonic code, but others much greater than I have already done a terrific job of doing so [here](https://www.python.org/dev/peps/pep-0020/)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='Resource'></a>\n", + "# Resource List\n", + "General General Stuff\n", + "\n", + "1. [Chris Albon's Website](https://chrisalbon.com/#articles) which has super useful examples for Scikit Learn, Pandas, and ML in general\n", + "\n", + "2. [One of my own repo's](https://github.com/charlesxjyang/CollegeScoreCardReport) which I created awhile ago analyzing the Dept. of Education's CollegeScoreCard Report. Some more examples of pandas and matplotlib, as well as data analysis workflows in jupyter notebook.\n", + "\n", + "General Python Stuff\n", + "1. [CS61A](https://cs61a.org/)\n", + "2. [Free Online Textbook based on CS61A](http://composingprograms.com/)\n", + "3. [Python3 Documentation](https://docs.python.org/3/)\n", + "\n", + "\n", + "Matplotlib\n", + "1. [Matplotlib Tutorials](https://matplotlib.org/tutorials/index.html)\n", + "2. [Seaborn](https://seaborn.pydata.org/) is a wrapper for Matplotlib, but can make simple graphs look really beautiful.\n", + "\n", + "Pandas\n", + "1. [Pandas Documentation](https://pandas.pydata.org/pandas-docs/stable/)\n", + "\n", + "Some Machine Learning\n", + "1. [Scikit Learn Overview](http://scikit-learn.org/stable/documentation.html)\n", + "2. [Scikit Learn ML Introduction](http://scikit-learn.org/stable/tutorial/basic/tutorial.html)\n", + "***\n", + "The following are comprehensive online resources that dive quite deep into the underlying math and mechanics of ML. In particular, the Coursera courses are ones I personally used and can take you quite far in terms of material and understanding. Although challenging, I would highly recommend these for anyone who really wants to specialize or dive deeper into this field. Plus, these courses are usually taught by the people who founded this field, which I personally find to be a super cool experience.\n", + "\n", + "[Coursera Machine Learning](https://www.coursera.org/learn/machine-learning)\n", + "\n", + "[Coursera Deep Learning Specialization](https://www.coursera.org/specializations/deep-learning)\n", + "\n", + "[Coursera Neural Network Course](https://www.coursera.org/learn/neural-networks)\n", + "\n", + "[Stanford's CS229 Machine Learning](http://cs229.stanford.edu/)\n", + "\n", + "[Stanford's CS231n Image Processing with Neural Networks Class](http://cs231n.stanford.edu/)\n" + ] + } + ], + "metadata": { + "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.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Lab3.ipynb b/notebooks/Lab3.ipynb index 8aa33e7..83a2ec7 100644 --- a/notebooks/Lab3.ipynb +++ b/notebooks/Lab3.ipynb @@ -1,477 +1,526 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Lab 3: T Cell Differentiation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# imports\n", - "from datascience import Table\n", - "import matplotlib\n", - "matplotlib.use('Agg')\n", - "from datascience import Table\n", - "%matplotlib inline\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "plt.style.use('fivethirtyeight')\n", - "from sklearn.cluster import KMeans\n", - "from IPython.display import Markdown as md" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Part 1\n", - "This lab, as well as following labs, will use the datascience API. For more information about the datascience Table API, see http://data8.org/datascience/tutorial.html#getting-started.\n", - "\n", - "For part 1 of the lab, we will investigate the expression of 24923 genes in CD8+ T cells over time.\n", - "\n", - "These mice were injected with naive T cells that have a T cell receptor (TCR) which is specific for an epitope from the ovalbumin (ov) protein. These mice were then were infected with two different viruses: vesicular stomatitis virus (VSV) and listeria bacterium (LisOva).\n", - "\n", - "VSV infected mice were sampled over 106 days. Lis infected mice were sampled over 100 days. These time points demonstrate differentiation in expression of genes as the CD8+ T Cells are introduced the the ov epitope after infection.\n", - "\n", - "This data is from the Immgen database, and can be can be explored at the [Immgen Population Comparison](http://rstats.immgen.org/PopulationComparison/). This dataset was downloaded from [ImmGen DataRequest](http://rstats.immgen.org/DataRequest/) for activated T cells.\n", - "\n", - "## Load in the Data\n", - "\n", - "1. First, load in the data for containing T Cell expression using the read_table function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# load in data for part 1\n", - "table1 = Table.read_table('https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab3/rnaseq_Tcell_quantifications.csv')\n", - "table1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What do the table headers mean?\n", - "For each gene, we are given a gene symbol and description. We are also given a value for each time point in each cell type. These values are drawn from microarray experiments, and measure the flourescence of hybridization of each gene to a probe. The higher the measure of flourescence, the greater the expression of RNA at that probe. Note that all probes are specific to a given gene." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The data loaded in shows 24923 probes and their expression over 100 days of incubation. \n", - "\n", - "First, let's sort the genes by naive expression. First, we will sort in order of descending expression to find the 3 highest expressed genes." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# First, select the Gene symbol and mean expression columns\n", - "expression = table1.select(['GeneSymbol', 'T_8Nve_Sp_OT1'])\n", - "\n", - "# Next, sort by mean expression. Set descending to true.\n", - "sortedDescending = expression.sort('T_8Nve_Sp_OT1', descending = True)\n", - "\n", - "# Select the top expressed genes\n", - "sortedDescending" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, we see the highest expressed genes are LOC236598, Rn18s, and Eef1a1.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 1**</h2> \n", - "\n", - "Using the **sort()** functionality for table, what are the top 3 expressed genes and their expression values for late memory cells (days = 106) infected with VSVOva? \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer here:\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 2**</h2> \n", - "Using the **sort()** functionality for table, what are the top 3 expressed genes and their expression values for late effector cells (days = 8) infected with VSVOva? " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer here\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "<h2 style=\"color:red\">** Question 3**</h2> \n", - "Is there any overlap between the most highly expressed genes in naive, effector and memory? What does it mean if there are genes highly expressed in all three groups? " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer:\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 4**</h2> \n", - "Is there any differentially expressed genes in naive, effector and memory? What does it mean if there are differentially expressed genes across categories?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer:\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Part 2: K Means Clustering of Microarray Probe Intensities" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For part 2 of the lab, we will cluster genes based on their gene specific probe intensities over 100 days. The goal of this exercise is to find relationships among genes using k-means clustering. A description of k-means clustering can be found here: \n", - "We will be using the sklearn implementation: http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, we will load in the data for a subset of the probes. We will use these to filter our original dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# load in a list of probe IDs we are interested in clustering\n", - "fileProbes = Table.read_table('https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab3/cluster_probes.csv')\n", - "\n", - "# get the probe IDs from the table and convert to a list\n", - "filteredProbes = list(fileProbes.to_df().columns)\n", - "filteredProbes = list(map(int, filteredProbes))\n", - "filteredProbes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# filter the data with the selected gene symbols\n", - "allProbes = table1[\"ProbeSetID\"].tolist() \n", - "\n", - "# make empty list to hold booleans for geneSymbols\n", - "bools = list(range(len(allProbes)))\n", - "\n", - "# assign bools to whether or not gene symbol was found\n", - "# in our filtered list geneSymbols\n", - "for index, i in enumerate(allProbes):\n", - " if i in filteredProbes:\n", - " bools[index] = True\n", - " else:\n", - " bools[index] = False\n", - "\n", - "# filter table by geneSymbol booleans \n", - "table2 = table1.where(bools)\n", - "table2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Fit 10 clusters to the all genes available in our dataset. You first must convert the dataframe into an np matrix. To do so, select relevant columns, then call `table.to_df().as_matrix()`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Select the expression columns for 0 to 100 days\n", - "columns = table2.select(['T_8Nve_Sp_OT1', 'T_8Eff_Sp_OT1_d5_VSVOva', 'T_8Eff_Sp_OT1_d6_VSVOva', \\\n", - " 'T_8Eff_Sp_OT1_d8_VSVOva', 'T_8Eff_Sp_OT1_d15_VSVOva', 'T_8Mem_Sp_OT1_d45_VSVOva', \\\n", - " 'T_8Mem_Sp_OT1_d106_VSVOva'])\n", - "\n", - "# To use kmeans, we must format our data as a matrix. These functions let us extract a matrix of values from our table \n", - "# of expression data.\n", - "matrix = columns.to_df().as_matrix()\n", - "\n", - "# Run kmeans with 10 clusters\n", - "kmeans = KMeans(n_clusters=10, random_state=0).fit(matrix)\n", - "\n", - "# Print out the cluster labels. Each label 0-9 represents a different cluster. Genes in the same cluster should have \n", - "#'similar' expression patterns. \n", - "kmeans_labels = kmeans.labels_\n", - "print(kmeans_labels)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we will plot time series data for cluster 1 over time from 0 to 100 days of incubation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Add a new column to our table that holds the cluster label kmeans assigned.\n", - "columns_and_labels = columns.with_column('cluster_id', kmeans.labels_.tolist())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Get genes that were clustered into cluster 0. Drop the cluster column for plotting.\n", - "cluster_0 = columns_and_labels.where('cluster_id', 0).drop('cluster_id')\n", - "\n", - "# get figure and axes for plot\n", - "fig, ax = plt.subplots()\n", - "\n", - "# Graphing a line for each gene is tricky. To do this, we will be converting our data to a matrix, \n", - "# then using matplotlib. 'T' transposes our data.\n", - "x=cluster_0.to_df().as_matrix().T\n", - "\n", - "# Plot each gene using matplotlib.\n", - "results = ax.plot(x)\n", - "\n", - "# set labels to incubation days\n", - "labels = ['', 'Nve', 'd5', 'd6', 'd8', 'd15', 'd45', 'd106']\n", - "# rewrite labels\n", - "ax.set_xticklabels(labels)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 5**</h2> \n", - "Following the instructions from the cell above, plot all of the 10 clusters on a subplot. (Hint: you should use a loop so you don't have to re-write code 9 times.) **Make sure to label and title your plots for full credit.**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer here:\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 6**</h2> \n", - "What are some trends you can see between and across gene clusters over time?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 7**</h2> \n", - "List all of the genes in each of the categories. (Hint: We printed out the labels for each gene above. This is stored in the **kmeans_labels** array. Join this with the Gene names, and print the gene names in each cluster." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer here:\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 8**</h2> " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Which clusters have the most genes in them? Which cluster have the fewest genes in them?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 9**</h2> \n", - "Open https://www.immgen.org/ImmGenPublications/ni.2536.pdf. This paper contains the original clustering experiments of this gene set. In Figure 1c, you can see their 10 clusters. Read the genes in each of these clusters. Which of your clusters correspond to the clusters they found in the paper (ie Cluster 1 from paper -> my cluster 2). If unsure of specific, you can put 2 clusters." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 10**</h2> \n", - "It seems like our clusting results differ from those in the paper. What are some potential sources that are creating these differences?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 11**</h2> \n", - "\n", - "Pick one of the 10 clusters defined in the paper. Give a description of the category from the paper and explain one of its genes. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "<h2 style=\"color:red\">** Question 12**</h2> \n", - "On a scale from 1 to 10 (1 being worst, 10 being best), please rate this lab in terms of its:\n", - "1. Clarity\n", - "2. Difficulty\n", - "3. Length\n", - "4. Insight" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "**Answer here:**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.6.1" - }, - "timetravel": { - "allowedContentTypes": [ - "text/plain" - ], - "enabled": false, - "version": "1.0" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lab 3: T Cell Differentiation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# imports\n", + "from datascience import Table\n", + "import matplotlib\n", + "matplotlib.use('Agg')\n", + "from datascience import Table\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "plt.style.use('fivethirtyeight')\n", + "from sklearn.cluster import KMeans\n", + "from IPython.display import Markdown as md" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Part 1\n", + "This lab, as well as following labs, will use the datascience API. For more information about the datascience Table API, see http://data8.org/datascience/tutorial.html#getting-started.\n", + "\n", + "For part 1 of the lab, we will investigate the expression of 24923 genes in CD8+ T cells over time.\n", + "\n", + "These mice were injected with naive T cells that have a T cell receptor (TCR) which is specific for an epitope from the ovalbumin (ov) protein. These mice were then were infected with two different viruses: vesicular stomatitis virus (VSV) and listeria bacterium (LisOva).\n", + "\n", + "VSV infected mice were sampled over 106 days. Lis infected mice were sampled over 100 days. These time points demonstrate differentiation in expression of genes as the CD8+ T Cells are introduced the the ov epitope after infection.\n", + "\n", + "This data is from the Immgen database, and can be can be explored at the [Immgen Population Comparison](http://rstats.immgen.org/PopulationComparison/). This dataset was downloaded from [ImmGen DataRequest](http://rstats.immgen.org/DataRequest/) for activated T cells.\n", + "\n", + "## Load in the Data\n", + "\n", + "1. First, load in the data for containing T Cell expression using the read_table function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# load in data for part 1\n", + "table1 = Table.read_table('https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab3/rnaseq_Tcell_quantifications.csv')\n", + "table1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### What do the table headers mean?\n", + "For each gene, we are given a gene symbol and description. We are also given a value for each time point in each cell type. These values are drawn from microarray experiments, and measure the flourescence of hybridization of each gene to a probe. The higher the measure of flourescence, the greater the expression of RNA at that probe. Note that all probes are specific to a given gene." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The data loaded in shows 24923 probes and their expression over 100 days of incubation. \n", + "\n", + "First, let's sort the genes by naive expression. First, we will sort in order of descending expression to find the 3 highest expressed genes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# First, select the Gene symbol and mean expression columns\n", + "expression = table1.select(['GeneSymbol', 'T_8Nve_Sp_OT1'])\n", + "\n", + "# Next, sort by mean expression. Set descending to true.\n", + "sortedDescending = expression.sort('T_8Nve_Sp_OT1', descending = True)\n", + "\n", + "# Select the top expressed genes\n", + "sortedDescending" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, we see the highest expressed genes are LOC236598, Rn18s, and Eef1a1.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 1**</h2> \n", + "\n", + "Using the **sort()** functionality for table, what are the top 3 expressed genes and their expression values for late memory cells (days = 106) infected with VSVOva? \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Answer here:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 2**</h2> \n", + "Using the **sort()** functionality for table, what are the top 3 expressed genes and their expression values for late effector cells (days = 8) infected with VSVOva? " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Answer here\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "<h2 style=\"color:red\">** Question 3**</h2> \n", + "Is there any overlap between the most highly expressed genes in naive, effector and memory? What does it mean if there are genes highly expressed in all three groups? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 4**</h2> \n", + "Is there any differentially expressed genes in naive, effector and memory? What does it mean if there are differentially expressed genes across categories?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Part 2: K Means Clustering of Microarray Probe Intensities" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For part 2 of the lab, we will cluster genes based on their gene specific probe intensities over 100 days. The goal of this exercise is to find relationships among genes using k-means clustering, a common machine-learning technique for unsupervised learning.\n", + "\n", + "For the curious: \n", + "A description of k-means clustering can be found here: http://stanford.edu/~cpiech/cs221/handouts/kmeans.html\n", + "A more python-focused implementation of k-means can be found here: https://mubaris.com/2017/10/01/kmeans-clustering-in-python/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In short, k-means clustering is a method to group a dataset. Using an iterative algorithm, k-means can identify relationships between seemingly disparate data points and deeper patterns than predicted by theory.\n", + "Rather than implementing our own k-means algorithm(which can take quite some time), we will use someone else's! As it is much more likely to be developed, optimized, and tested, we can build off of other's work while saving time ourselves.\n", + "\n", + "In particular, we will be using the sklearn implementation: http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html/\n", + "Sklearn is an excellent data science and modelling package in Python and can run just about any model one could desire(besides neural networks), all of which follow a simple, easy-to-understand API. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, we will load in the data for a subset of the probes. We will use these to filter our original dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load in a list of probe IDs we are interested in clustering\n", + "fileProbes = Table.read_table('https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab3/cluster_probes.csv')\n", + "\n", + "# get the probe IDs from the table and convert to a list\n", + "filteredProbes = list(fileProbes.to_df().columns)\n", + "filteredProbes = list(map(int, filteredProbes))\n", + "filteredProbes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# filter the data with the selected gene symbols\n", + "allProbes = table1[\"ProbeSetID\"].tolist() \n", + "\n", + "# make empty list to hold booleans for geneSymbols\n", + "bools = list(range(len(allProbes)))\n", + "\n", + "# assign bools to whether or not gene symbol was found\n", + "# in our filtered list geneSymbols\n", + "for index, i in enumerate(allProbes):\n", + " if i in filteredProbes:\n", + " bools[index] = True\n", + " else:\n", + " bools[index] = False\n", + "\n", + "# filter table by geneSymbol booleans \n", + "table2 = table1.where(bools)\n", + "table2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Fit 10 clusters to the all genes available in our dataset. You first must convert the dataframe into an np matrix. To do so, select relevant columns, then call `table.to_df().as_matrix()`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Select the expression columns for 0 to 100 days\n", + "columns = table2.select(['T_8Nve_Sp_OT1', 'T_8Eff_Sp_OT1_d5_VSVOva', 'T_8Eff_Sp_OT1_d6_VSVOva', \\\n", + " 'T_8Eff_Sp_OT1_d8_VSVOva', 'T_8Eff_Sp_OT1_d15_VSVOva', 'T_8Mem_Sp_OT1_d45_VSVOva', \\\n", + " 'T_8Mem_Sp_OT1_d106_VSVOva'])\n", + "\n", + "# To use kmeans, we must format our data as a matrix. These functions let us extract a matrix of values from our table \n", + "# of expression data.\n", + "matrix = columns.to_df().as_matrix()\n", + "\n", + "# Run kmeans with 10 clusters\n", + "kmeans = KMeans(n_clusters=10, random_state=0).fit(matrix)\n", + "\n", + "# Print out the cluster labels. Each label 0-9 represents a different cluster. Genes in the same cluster should have \n", + "#'similar' expression patterns. \n", + "kmeans_labels = kmeans.labels_\n", + "print(kmeans_labels)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we will plot time series data for cluster 1 over time from 0 to 100 days of incubation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Add a new column to our table that holds the cluster label kmeans assigned.\n", + "columns_and_labels = columns.with_column('cluster_id', kmeans.labels_.tolist())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Get genes that were clustered into cluster 0. Drop the cluster column for plotting.\n", + "cluster_0 = columns_and_labels.where('cluster_id', 0).drop('cluster_id')\n", + "\n", + "# get figure and axes for plot\n", + "fig, ax = plt.subplots()\n", + "\n", + "# Graphing a line for each gene is tricky. To do this, we will be converting our data to a matrix, \n", + "# then using matplotlib. 'T' transposes our data.\n", + "x=cluster_0.to_df().as_matrix().T\n", + "\n", + "# Plot each gene using matplotlib.\n", + "results = ax.plot(x)\n", + "\n", + "# set labels to incubation days\n", + "labels = ['', 'Nve', 'd5', 'd6', 'd8', 'd15', 'd45', 'd106']\n", + "# rewrite labels\n", + "ax.set_xticklabels(labels)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 5**</h2> \n", + "Using the matplotlib.pyplot \n", + "Following the instructions from the cell above, plot all of the 10 clusters on a subplot. (Hint: you should use a loop so you don't have to re-write code 9 times.) **Make sure to label and title your plots for full credit.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# get figure and axes for plot\n", + "fig, ax = plt.subplots()\n", + "for i in range(10):\n", + " '''Fill in the rest of this code'''\n", + " cluster = \n", + " cluster_matrix = cluster.to_df().as_matrix().T\n", + " ax.plt(cluster_matrix)\n", + " \n", + "\n", + "# set labels to incubation days\n", + "labels = ['', 'Nve', 'd5', 'd6', 'd8', 'd15', 'd45', 'd106']\n", + "# rewrite labels\n", + "ax.set_xticklabels(labels)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 6**</h2> \n", + "What are some trends you can see between and across gene clusters over time?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Answer here:**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 7**</h2> \n", + "List all of the genes in each of the categories. (Hint: We printed out the labels for each gene above. This is stored in the **kmeans_labels** array. Join this with the Gene names, and print the gene names in each cluster." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Answer here:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 8**</h2> " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Which clusters have the most genes in them? Which cluster have the fewest genes in them?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Answer here:**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 9**</h2> \n", + "Open https://www.immgen.org/ImmGenPublications/ni.2536.pdf. This paper contains the original clustering experiments of this gene set. In Figure 1c, you can see their 10 clusters. Read the genes in each of these clusters. Which of your clusters correspond to the clusters they found in the paper (ie Cluster 1 from paper -> my cluster 2). If unsure of specific, you can put 2 clusters." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Answer here:**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 10**</h2> \n", + "It seems like our clusting results differ from those in the paper. What are some potential sources that are creating these differences?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Answer here:**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 11**</h2> \n", + "\n", + "Pick one of the 10 clusters defined in the paper. Give a description of the category from the paper and explain one of its genes. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Answer here:**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "<h2 style=\"color:red\">** Question 12**</h2> \n", + "On a scale from 1 to 10 (1 being worst, 10 being best), please rate this lab in terms of its:\n", + "1. Clarity\n", + "2. Difficulty\n", + "3. Length\n", + "4. Insight" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Answer here:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "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.6.2" + }, + "timetravel": { + "allowedContentTypes": [ + "text/plain" + ], + "enabled": false, + "version": "1.0" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/notebooks/Lab4.ipynb b/notebooks/Lab4.ipynb index 3209389..f833bfe 100644 --- a/notebooks/Lab4.ipynb +++ b/notebooks/Lab4.ipynb @@ -1,482 +1,692 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Chromatin Differentiation in Dysfunctional T cells" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# imports\n", - "from datascience import Table\n", - "%matplotlib inline\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All data in this lab comes from https://www.nature.com/articles/nature22367. This paper, titled 'Chromatin states define tumour-specific T cell dysfunction and reprogramming', collects ATAC-seq data from normal and dysfunctional T cells that were immunized with Listeria monoctgogenes strain. Here, we compare the accessibility between these two groups. Today, we will look at this datasets to draw similar conclusions regarding the change in epigenetic state of T cell dysfunction.\n", - "\n", - "Data can be found at https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE89309.\n", - "\n", - "First, load in the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "table = Table.read_table('https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab4/dysfunctional_ATACseq_timeseries.csv')\n", - "table" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this dataset, each peak has a location (chr, start and end) as well as an associated gene symbol. The peak annotation tells us where the peak occurs.\n", - "\n", - "The rest of the dataset has labels N1, E5, E7, ... L60_3. These abbreviations stand for the following:\n", - "\n", - "<h3>Normal T Cells</h3> \n", - "\n", - "- N1: Naive T cell\n", - "- E5: Effector cell after incubated for 5 days\n", - "- E7: Effector cell after incubated for 7 days\n", - "- M1: Memory cell\n", - "\n", - "<h3>Dysfunctional T Cells</h3> \n", - "\n", - "- L5: Dysfunctional T cells after 5 days\n", - "- L7: Dysfunctional T cells after 7 days\n", - "- L14: Dysfunctional T cells after 14 days\n", - "- L21: Dysfunctional T cells after 21 days\n", - "- L28: Dysfunctional T cells after 28 days\n", - "- L35: Dysfunctional T cells after 35 days\n", - "- L60: Dysfunctional T cells after 60 days\n", - "\n", - "You may notice there are multiple samples for each category (i.e. E5_1, E5_2, E5_3). These represent biological replicates.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 1**</h2> \n", - "\n", - "How many ATAC-seq peaks does this dataset have?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer here\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 2**</h2> \n", - "\n", - "Is there more or less ATAC-seq peaks in this dataset than you would expect in the same dataset for RNA-seq? Explain." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 1: Exploring differential accessibility in normal T Cells\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For part 1 of the lab, we will compare differentially accessible regions between different T cell activation states in normal T cells. To do this, we need a method that can calculate whether the value of a gene in two cell states is statistically significant. To determine whether sites are significantly different, we need a **peak calling** algorithm. These algorithms are able to determine which genes are significantly differentially accessible between two states (i.e. naive and effector). We will use our own peak calling algorithm to calculate differential peaks.\n", - "\n", - "First, let us define a peak calling function called **callPeaks()**:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def callPeaks(table, CAT1_NAMES, CAT2_NAMES):\n", - " '''\n", - " Calls peaks on two categories of peak calling data. Can be used for ATAC-seq or RNA-seq.\n", - " Borrowed from http://dept.stat.lsa.umich.edu/~kshedden/Python-Workshop/gene_expression_comparison.html\n", - "\n", - " param1: Table data: takes for from \n", - " https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab4/dysfunctional_ATACseq_timeseries.csv\n", - " param1: column names of first category\n", - " param2: column names of second category\n", - " return: Table of differentially called regions\n", - " Positive values mean the peak was siginificantly higher in the first category\n", - " Negative values mean the peak was significantly higher in the second category\n", - " '''\n", - "\n", - " # gene list\n", - " GID = list(table.column('symbol'))\n", - "\n", - " # matrix of values\n", - " dropped = table.drop(['chr', 'start', 'end', 'symbol','refseqID', 'peak_annotation'])\n", - " X = np.array(dropped.to_df().as_matrix())\n", - " # list of categories\n", - " SID = list(table.column_labels)[6:]\n", - " \n", - " # get indices of category names\n", - " CAT1 = [list(dropped.column_labels).index(i) for i in CAT1_NAMES]\n", - " CAT2 = [list(dropped.column_labels).index(i) for i in CAT2_NAMES]\n", - " \n", - "\n", - " ## Convert X to log scale\n", - " XL = np.log(X) / np.log(2)\n", - "\n", - " M1 = XL[:,CAT1].mean(1) ## Mean of category 1 samples for each data point\n", - " M2 = XL[:,CAT2].mean(1) ## Mean of category2 samples for each data point\n", - " V1 = XL[:,CAT1].var(1) ## Variance of category 1 samples for each data point\n", - " V2 = XL[:,CAT2].var(1) ## Variance of category 2 samples for each data point\n", - " n1 = len(CAT1) ## Number of category 1 samples\n", - " n2 = len(CAT2) ## Number of category 2 samples\n", - "\n", - " # calculate Z score\n", - " Z = (M1 - M2) / np.sqrt(V1/n1 + V2/n2)\n", - "\n", - " ## Gaussian distribution CDF, pdf, quantile function, etc.\n", - " from scipy.stats.distributions import norm\n", - "\n", - " ## The Z-score threshold under a Bonferroni correction\n", - " zst = -norm.ppf(0.025/Z.shape[0])\n", - "\n", - " # indices of differentially expressed genes\n", - " ii = np.flatnonzero(np.abs(Z) > zst) \n", - " scores = Z[ii] # scores\n", - " genes = np.array(GID)[ii] # gene names\n", - " annotation = np.array(table.column('peak_annotation'))[ii]\n", - " chr = np.array(table.column('chr'))[ii]\n", - " start = np.array(table.column('start'))[ii]\n", - " end = np.array(table.column('end'))[ii]\n", - "\n", - " # create new table with differential regions\n", - " newTable = Table().with_columns(['chr', chr, 'start', start, 'end', end,'peak_annotation', annotation, 'symbol', genes, 'score', scores])\n", - "\n", - " return newTable\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This method takes as input the data table we are analyzing, as well as the column names of the first category and second category we would like to compare. For example, let's compare naive and 5 day effector states:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# get column names of category 1 and 2\n", - "CAT1_NAMES = ['N1','N2','N3'] \n", - "CAT2_NAMES = ['E5_1','E5_2','E5_3']\n", - "\n", - "calledPeaksN = callPeaks(table, CAT1_NAMES, CAT2_NAMES)\n", - "\n", - "calledPeaksN" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The score column contains how different the peak was between the two categories. Positive values demonstrate peaks more accessible in the first category (i.e. more accessible in naive). Negative values demonstrate peaks more accessible in the second category (i.e. more accessible in effector)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 3**</h2> \n", - "\n", - "How many peaks in the table above are more accessible in 5 day effector cells, compared to naive cells?\n", - "How many peaks in the table above are less accessible in 5 day effector cells, compared to naive cells? (Save these values as variables, we will be plotting them later)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer here:\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 4**</h2> \n", - "\n", - "Repeat this process to find the number of differentially accessible peaks for the transition from E5 to E7.\n", - "\n", - "How many peaks in the table above are more accessible in 7 day effector cells, compared to 5 day effector cells?\n", - "How many peaks in the table above are less accessible in 7 day effector cells, compared to 5 day effector cells? (Save these values as variables, we will be plotting them later)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 5**</h2> \n", - "\n", - "Repeat this process to find the number of differentially accessible peaks for the transition from E7 to M.\n", - "\n", - "How many peaks in the table above are more accessible in memory cells, compared to 7 day effector cells?\n", - "How many peaks in the table above are less accessible in memory cells, compared to 7 day effector cells? (Save these values as variables, we will be plotting them later)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 6**</h2> \n", - "\n", - "Make a bar plot that shows shows these changes in accessibility for the transitions N->E5, E5->E7, and E7->M. Plot closed peaks as negative values for easier viewing. There should be 6 total bars on the plot. Make sure to label the axes. (Hint: To make this plot, you can make a new table with the values computed above, or use matplotlib.) If you are unsure of what this plot may sort of look at, reference Figure 1B in the paper for help." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 7**</h2> \n", - "\n", - "Given the bar chart above, which transition has the fewest differences in accessibily? Which transition has the most changes in accessibily?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**\n", - "\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we will look at some of the genes and observe how their accessibility peaks change over T cell activation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 8**</h2> \n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 2: Comparing Normal and Dysfunction T cell accessibility\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we will compare the normal effector states (E5/E7) to dysfunctional T cell states (L5/L7)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 9**</h2> \n", - "\n", - "Run the peak calling algorithm, differentiating peaks between normal effector states (E5/E7) and dysfunctional T cell states (L5/L7). Print the resulting table." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 10**</h2> \n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "# Answer\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 3: Viewing ATAC-seq data in UCSC Genome Browser" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we will view a couple accessibility sites for activated T cells in the UCSC genome browser. \n", - "\n", - "1. Navigate to http://rstats.immgen.org/Chromatin/chromatin.html. \n", - "2. Select ab T cells. Under the ab T cell category, select all of the NK (natural killer) cell categories. There are 4.\n", - "\n", - "3. Search for the gene 'Gzma' and click 'View data on UCSC Genome Browser'\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 11**</h2> \n", - "Viewing Gzma in the genome browser, does the naive cell (NKT_Sp) look more or less accessible than the other three activated cell states?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer here:**\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Question 12**</h2> \n", - "Navigate to gene cards (http://www.genecards.org/) and search for the gene **Gzma** and read the description. What process is this gene involved in? Does the function of this gene align with the accessibility trends you observed in the previous question? Explain." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "** Answer here:**\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "<h2 style=\"color:red\">** Bonus Question**</h2> \n", - "Describe, in words, how the peak calling algorithm works." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "** Answer here**:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Chromatin Differentiation in Dysfunctional T cells" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# imports\n", + "from datascience import Table\n", + "%matplotlib inline\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All data in this lab comes from https://www.nature.com/articles/nature22367. This paper, titled 'Chromatin states define tumour-specific T cell dysfunction and reprogramming', collects ATAC-seq data from normal and dysfunctional T cells that were immunized with Listeria monoctgogenes strain. Here, we compare the accessibility between these two groups. Today, we will look at this datasets to draw similar conclusions regarding the change in epigenetic state of T cell dysfunction.\n", + "\n", + "Data can be found at https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE89309.\n", + "\n", + "First, load in the data." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr>\n", + " <th>chr</th> <th>start</th> <th>end</th> <th>symbol</th> <th>refseqID</th> <th>peak_annotation</th> <th>N1</th> <th>N2</th> <th>N3</th> <th>E5_1</th> <th>E5_2</th> <th>E5_3</th> <th>E7_2</th> <th>E7_3</th> <th>M1</th> <th>M2</th> <th>M3</th> <th>L5_1</th> <th>L5_2</th> <th>L5_3</th> <th>L5_4</th> <th>L7_1</th> <th>L7_2</th> <th>L7_3</th> <th>L14_1</th> <th>L14_2</th> <th>L14_3</th> <th>L21_1</th> <th>L21_2</th> <th>L21_3</th> <th>L28_1</th> <th>L28_2</th> <th>L28_3</th> <th>L35_1</th> <th>L35_2</th> <th>L35_3</th> <th>L60_1</th> <th>L60_2</th> <th>L60_3</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>9772732 </td> <td>9773228 </td> <td>1700034P13Rik</td> <td>NR_040462</td> <td>intergenic </td> <td>209.153</td> <td>221.576</td> <td>241.935</td> <td>129.291</td> <td>148.714</td> <td>132.882</td> <td>150.143</td> <td>189.593</td> <td>255.555</td> <td>270.364</td> <td>236.631</td> <td>113.379</td> <td>113.803</td> <td>123.402</td> <td>128.035</td> <td>113.542</td> <td>145.413</td> <td>153.614</td> <td>125.268</td> <td>124.401</td> <td>145.569</td> <td>205.532</td> <td>221.787</td> <td>193.068</td> <td>243.36 </td> <td>145.573</td> <td>197.799</td> <td>167.201</td> <td>180.65 </td> <td>159.028</td> <td>147.345</td> <td>180.696</td> <td>166.505</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>9797805 </td> <td>9798616 </td> <td>Sgk3 </td> <td>NM_133220</td> <td>promoter </td> <td>538.113</td> <td>596.551</td> <td>655.475</td> <td>355.311</td> <td>294.949</td> <td>347.62 </td> <td>390.926</td> <td>387.085</td> <td>542.902</td> <td>707.899</td> <td>495.03 </td> <td>249.435</td> <td>323.829</td> <td>393.837</td> <td>393.25 </td> <td>299.414</td> <td>284.931</td> <td>417.973</td> <td>291.065</td> <td>237.629</td> <td>237.223</td> <td>275.05 </td> <td>264.352</td> <td>234.588</td> <td>274.863</td> <td>255.656</td> <td>302.111</td> <td>214.586</td> <td>214.048</td> <td>170.021</td> <td>216.862</td> <td>155.424</td> <td>201.024</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>9859046 </td> <td>9859750 </td> <td>Sgk3 </td> <td>NM_133220</td> <td>intron </td> <td>178.694</td> <td>186.59 </td> <td>187.546</td> <td>702.002</td> <td>616.336</td> <td>559.168</td> <td>671.84 </td> <td>641.004</td> <td>666.4 </td> <td>769.815</td> <td>579.29 </td> <td>231.992</td> <td>248.886</td> <td>370.207</td> <td>397.823</td> <td>432.299</td> <td>350.76 </td> <td>405.469</td> <td>257.905</td> <td>290.518</td> <td>273.423</td> <td>384.616</td> <td>357.324</td> <td>311.4 </td> <td>224.458</td> <td>333.255</td> <td>311.951</td> <td>286.34 </td> <td>274.012</td> <td>367.89 </td> <td>163.213</td> <td>180.696</td> <td>226.406</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>10089499</td> <td>10089955</td> <td>Cspp1 </td> <td>NM_026493</td> <td>intron </td> <td>251.796</td> <td>204.532</td> <td>209.114</td> <td>161.853</td> <td>113.188</td> <td>126.504</td> <td>170.901</td> <td>202.007</td> <td>235.991</td> <td>212.576</td> <td>153.775</td> <td>97.6808</td> <td>111.027</td> <td>110.274</td> <td>121.938</td> <td>117.747</td> <td>114.955</td> <td>162.545</td> <td>127.11 </td> <td>108.013</td> <td>179.458</td> <td>161.705</td> <td>210.586</td> <td>167.118</td> <td>191.38 </td> <td>141.362</td> <td>184.022</td> <td>150.955</td> <td>193.554</td> <td>201.533</td> <td>148.101</td> <td>190.805</td> <td>191.887</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>12875425</td> <td>12875883</td> <td>Slco5a1 </td> <td>NM_172841</td> <td>intron </td> <td>185.801</td> <td>126.487</td> <td>137.847</td> <td>131.206</td> <td>115.666</td> <td>144.576</td> <td>143.916</td> <td>135.423</td> <td>176.076</td> <td>189.874</td> <td>126.391</td> <td>125.59 </td> <td>123.055</td> <td>149.658</td> <td>195.101</td> <td>203.534</td> <td>105.13 </td> <td>210.773</td> <td>198.034</td> <td>196.658</td> <td>200.253</td> <td>281.095</td> <td>228.508</td> <td>230.436</td> <td>353.621</td> <td>300.17 </td> <td>307.031</td> <td>326.278</td> <td>255.036</td> <td>312.926</td> <td>272.777</td> <td>295.685</td> <td>341.132</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>13293331</td> <td>13293833</td> <td>Ncoa2 </td> <td>NM_008678</td> <td>intron </td> <td>305.607</td> <td>357.93 </td> <td>292.572</td> <td>203.035</td> <td>280.904</td> <td>248.755</td> <td>282.989</td> <td>226.834</td> <td>289.792</td> <td>251.789</td> <td>415.685</td> <td>172.686</td> <td>222.979</td> <td>212.672</td> <td>285.03 </td> <td>264.089</td> <td>211.242</td> <td>235.78 </td> <td>183.297</td> <td>265.936</td> <td>284.206</td> <td>315.854</td> <td>262.112</td> <td>290.64 </td> <td>367.009</td> <td>259.866</td> <td>274.557</td> <td>373.663</td> <td>335.494</td> <td>375.218</td> <td>334.738</td> <td>341.175</td> <td>342.148</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>20933432</td> <td>20933875</td> <td>Paqr8 </td> <td>NM_028829</td> <td>intron </td> <td>480.24 </td> <td>470.961</td> <td>512.94 </td> <td>267.201</td> <td>195.806</td> <td>223.242</td> <td>208.263</td> <td>273.104</td> <td>326.475</td> <td>375.62 </td> <td>339.148</td> <td>176.174</td> <td>271.091</td> <td>241.553</td> <td>233.207</td> <td>237.176</td> <td>280.018</td> <td>344.738</td> <td>227.509</td> <td>188.464</td> <td>250.317</td> <td>247.847</td> <td>250.911</td> <td>247.044</td> <td>215.795</td> <td>192.494</td> <td>224.369</td> <td>200.37 </td> <td>239.096</td> <td>244.771</td> <td>173.036</td> <td>245.14 </td> <td>222.345</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>23255935</td> <td>23256632</td> <td>Mir30a </td> <td>NR_029533</td> <td>intergenic </td> <td>681.271</td> <td>940.128</td> <td>810.201</td> <td>398.408</td> <td>372.61 </td> <td>407.151</td> <td>455.965</td> <td>457.054</td> <td>627.272</td> <td>1362.14</td> <td>870.691</td> <td>378.513</td> <td>401.548</td> <td>446.349</td> <td>495.374</td> <td>555.934</td> <td>445.082</td> <td>512.642</td> <td>233.036</td> <td>192.934</td> <td>331.958</td> <td>205.532</td> <td>254.271</td> <td>166.08 </td> <td>165.39 </td> <td>294.756</td> <td>137.77 </td> <td>158.401</td> <td>199.626</td> <td>240.374</td> <td>281.845</td> <td>235.032</td> <td>194.933</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>23762738</td> <td>23763139</td> <td>B3gat2 </td> <td>NM_172124</td> <td>promoter </td> <td>102.546</td> <td>82.5303</td> <td>58.1394</td> <td>168.557</td> <td>125.58 </td> <td>143.513</td> <td>152.219</td> <td>168.151</td> <td>397.394</td> <td>400.386</td> <td>193.097</td> <td>231.992</td> <td>215.577</td> <td>216.61 </td> <td>184.431</td> <td>300.255</td> <td>199.452</td> <td>185.766</td> <td>136.321</td> <td>113.228</td> <td>106.288</td> <td>144.326</td> <td>153.459</td> <td>107.952</td> <td>129.162</td> <td>153.393</td> <td>130.882</td> <td>111.693</td> <td>165.47 </td> <td>168.555</td> <td>151.879</td> <td>236.295</td> <td>138.077</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>33739113</td> <td>33739764</td> <td>Rab23 </td> <td>NM_008999</td> <td>exon </td> <td>248.75 </td> <td>276.297</td> <td>302.888</td> <td>239.428</td> <td>228.854</td> <td>186.035</td> <td>199.269</td> <td>268.59 </td> <td>231.1 </td> <td>284.811</td> <td>223.29 </td> <td>160.476</td> <td>183.195</td> <td>168.037</td> <td>245.4 </td> <td>204.375</td> <td>193.556</td> <td>207.2 </td> <td>228.43 </td> <td>238.374</td> <td>179.458</td> <td>221.4 </td> <td>229.628</td> <td>205.524</td> <td>176.417</td> <td>179.861</td> <td>266.684</td> <td>194.955</td> <td>233.783</td> <td>263.092</td> <td>163.969</td> <td>183.224</td> <td>159.398</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>... (75679 rows omitted)</p" + ], + "text/plain": [ + "chr | start | end | symbol | refseqID | peak_annotation | N1 | N2 | N3 | E5_1 | E5_2 | E5_3 | E7_2 | E7_3 | M1 | M2 | M3 | L5_1 | L5_2 | L5_3 | L5_4 | L7_1 | L7_2 | L7_3 | L14_1 | L14_2 | L14_3 | L21_1 | L21_2 | L21_3 | L28_1 | L28_2 | L28_3 | L35_1 | L35_2 | L35_3 | L60_1 | L60_2 | L60_3\n", + "chr1 | 9772732 | 9773228 | 1700034P13Rik | NR_040462 | intergenic | 209.153 | 221.576 | 241.935 | 129.291 | 148.714 | 132.882 | 150.143 | 189.593 | 255.555 | 270.364 | 236.631 | 113.379 | 113.803 | 123.402 | 128.035 | 113.542 | 145.413 | 153.614 | 125.268 | 124.401 | 145.569 | 205.532 | 221.787 | 193.068 | 243.36 | 145.573 | 197.799 | 167.201 | 180.65 | 159.028 | 147.345 | 180.696 | 166.505\n", + "chr1 | 9797805 | 9798616 | Sgk3 | NM_133220 | promoter | 538.113 | 596.551 | 655.475 | 355.311 | 294.949 | 347.62 | 390.926 | 387.085 | 542.902 | 707.899 | 495.03 | 249.435 | 323.829 | 393.837 | 393.25 | 299.414 | 284.931 | 417.973 | 291.065 | 237.629 | 237.223 | 275.05 | 264.352 | 234.588 | 274.863 | 255.656 | 302.111 | 214.586 | 214.048 | 170.021 | 216.862 | 155.424 | 201.024\n", + "chr1 | 9859046 | 9859750 | Sgk3 | NM_133220 | intron | 178.694 | 186.59 | 187.546 | 702.002 | 616.336 | 559.168 | 671.84 | 641.004 | 666.4 | 769.815 | 579.29 | 231.992 | 248.886 | 370.207 | 397.823 | 432.299 | 350.76 | 405.469 | 257.905 | 290.518 | 273.423 | 384.616 | 357.324 | 311.4 | 224.458 | 333.255 | 311.951 | 286.34 | 274.012 | 367.89 | 163.213 | 180.696 | 226.406\n", + "chr1 | 10089499 | 10089955 | Cspp1 | NM_026493 | intron | 251.796 | 204.532 | 209.114 | 161.853 | 113.188 | 126.504 | 170.901 | 202.007 | 235.991 | 212.576 | 153.775 | 97.6808 | 111.027 | 110.274 | 121.938 | 117.747 | 114.955 | 162.545 | 127.11 | 108.013 | 179.458 | 161.705 | 210.586 | 167.118 | 191.38 | 141.362 | 184.022 | 150.955 | 193.554 | 201.533 | 148.101 | 190.805 | 191.887\n", + "chr1 | 12875425 | 12875883 | Slco5a1 | NM_172841 | intron | 185.801 | 126.487 | 137.847 | 131.206 | 115.666 | 144.576 | 143.916 | 135.423 | 176.076 | 189.874 | 126.391 | 125.59 | 123.055 | 149.658 | 195.101 | 203.534 | 105.13 | 210.773 | 198.034 | 196.658 | 200.253 | 281.095 | 228.508 | 230.436 | 353.621 | 300.17 | 307.031 | 326.278 | 255.036 | 312.926 | 272.777 | 295.685 | 341.132\n", + "chr1 | 13293331 | 13293833 | Ncoa2 | NM_008678 | intron | 305.607 | 357.93 | 292.572 | 203.035 | 280.904 | 248.755 | 282.989 | 226.834 | 289.792 | 251.789 | 415.685 | 172.686 | 222.979 | 212.672 | 285.03 | 264.089 | 211.242 | 235.78 | 183.297 | 265.936 | 284.206 | 315.854 | 262.112 | 290.64 | 367.009 | 259.866 | 274.557 | 373.663 | 335.494 | 375.218 | 334.738 | 341.175 | 342.148\n", + "chr1 | 20933432 | 20933875 | Paqr8 | NM_028829 | intron | 480.24 | 470.961 | 512.94 | 267.201 | 195.806 | 223.242 | 208.263 | 273.104 | 326.475 | 375.62 | 339.148 | 176.174 | 271.091 | 241.553 | 233.207 | 237.176 | 280.018 | 344.738 | 227.509 | 188.464 | 250.317 | 247.847 | 250.911 | 247.044 | 215.795 | 192.494 | 224.369 | 200.37 | 239.096 | 244.771 | 173.036 | 245.14 | 222.345\n", + "chr1 | 23255935 | 23256632 | Mir30a | NR_029533 | intergenic | 681.271 | 940.128 | 810.201 | 398.408 | 372.61 | 407.151 | 455.965 | 457.054 | 627.272 | 1362.14 | 870.691 | 378.513 | 401.548 | 446.349 | 495.374 | 555.934 | 445.082 | 512.642 | 233.036 | 192.934 | 331.958 | 205.532 | 254.271 | 166.08 | 165.39 | 294.756 | 137.77 | 158.401 | 199.626 | 240.374 | 281.845 | 235.032 | 194.933\n", + "chr1 | 23762738 | 23763139 | B3gat2 | NM_172124 | promoter | 102.546 | 82.5303 | 58.1394 | 168.557 | 125.58 | 143.513 | 152.219 | 168.151 | 397.394 | 400.386 | 193.097 | 231.992 | 215.577 | 216.61 | 184.431 | 300.255 | 199.452 | 185.766 | 136.321 | 113.228 | 106.288 | 144.326 | 153.459 | 107.952 | 129.162 | 153.393 | 130.882 | 111.693 | 165.47 | 168.555 | 151.879 | 236.295 | 138.077\n", + "chr1 | 33739113 | 33739764 | Rab23 | NM_008999 | exon | 248.75 | 276.297 | 302.888 | 239.428 | 228.854 | 186.035 | 199.269 | 268.59 | 231.1 | 284.811 | 223.29 | 160.476 | 183.195 | 168.037 | 245.4 | 204.375 | 193.556 | 207.2 | 228.43 | 238.374 | 179.458 | 221.4 | 229.628 | 205.524 | 176.417 | 179.861 | 266.684 | 194.955 | 233.783 | 263.092 | 163.969 | 183.224 | 159.398\n", + "... (75679 rows omitted)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "table = Table.read_table('https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab4/dysfunctional_ATACseq_timeseries.csv')\n", + "table" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this dataset, each peak has a location (chr, start and end) as well as an associated gene symbol. The peak annotation tells us where the peak occurs.\n", + "\n", + "The rest of the dataset has labels N1, E5, E7, ... L60_3. These abbreviations stand for the following:\n", + "\n", + "<h3>Normal T Cells</h3> \n", + "\n", + "- N1: Naive T cell\n", + "- E5: Effector cell after incubated for 5 days\n", + "- E7: Effector cell after incubated for 7 days\n", + "- M1: Memory cell\n", + "\n", + "<h3>Dysfunctional T Cells</h3> \n", + "\n", + "- L5: Dysfunctional T cells after 5 days\n", + "- L7: Dysfunctional T cells after 7 days\n", + "- L14: Dysfunctional T cells after 14 days\n", + "- L21: Dysfunctional T cells after 21 days\n", + "- L28: Dysfunctional T cells after 28 days\n", + "- L35: Dysfunctional T cells after 35 days\n", + "- L60: Dysfunctional T cells after 60 days\n", + "\n", + "You may notice there are multiple samples for each category (i.e. E5_1, E5_2, E5_3). These represent biological replicates.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 1**</h2> \n", + "\n", + "How many ATAC-seq peaks does this dataset have?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## <span style=\"color:red\">Student Answer</span>\n", + "\n", + "*For the next question, double click on the text and add your answer below the question text*\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 2**</h2> \n", + "\n", + "Is there more or less ATAC-seq peaks in this dataset than you would expect in the same dataset for RNA-seq? Explain." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part 1: Exploring differential accessibility in normal T Cells\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For part 1 of the lab, we will compare differentially accessible regions between different T cell activation states in normal T cells. To do this, we need a method that can calculate whether the diffence in accessibility at a given genomic region in two cell states is statistically significant. To determine whether sites are significantly different, we need a **differential peak calling** algorithm. These algorithms are able to determine which genes are significantly differentially accessible between two states (i.e. naive and effector). We will use our own peak calling algorithm to calculate differential peaks.\n", + "\n", + "First, let us define a peak calling function called **callDifferentialPeaks()**:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def callDifferentialPeaks(table, CAT1_NAMES, CAT2_NAMES):\n", + " '''\n", + " Calls peaks on two categories of peak calling data. Can be used for ATAC-seq or RNA-seq.\n", + " Borrowed from http://dept.stat.lsa.umich.edu/~kshedden/Python-Workshop/gene_expression_comparison.html\n", + "\n", + " param1: Table data: takes for from \n", + " https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/data/lab4/dysfunctional_ATACseq_timeseries.csv\n", + " param1: column names of first category\n", + " param2: column names of second category\n", + " return: Table of differentially called regions\n", + " Positive values mean the peak was siginificantly higher in the first category\n", + " Negative values mean the peak was significantly higher in the second category\n", + " '''\n", + "\n", + " # gene list\n", + " GID = list(table.column('symbol'))\n", + "\n", + " # matrix of values\n", + " dropped = table.drop(['chr', 'start', 'end', 'symbol','refseqID', 'peak_annotation'])\n", + " X = np.array(dropped.to_df().as_matrix())\n", + " # list of categories\n", + " SID = list(table.column_labels)[6:]\n", + " \n", + " # get indices of category names\n", + " CAT1 = [list(dropped.column_labels).index(i) for i in CAT1_NAMES]\n", + " CAT2 = [list(dropped.column_labels).index(i) for i in CAT2_NAMES]\n", + " \n", + "\n", + " ## Convert X to log scale\n", + " XL = np.log(X) / np.log(2)\n", + "\n", + " M1 = XL[:,CAT1].mean(1) ## Mean of category 1 samples for each data point\n", + " M2 = XL[:,CAT2].mean(1) ## Mean of category2 samples for each data point\n", + " V1 = XL[:,CAT1].var(1) ## Variance of category 1 samples for each data point\n", + " V2 = XL[:,CAT2].var(1) ## Variance of category 2 samples for each data point\n", + " n1 = len(CAT1) ## Number of category 1 samples\n", + " n2 = len(CAT2) ## Number of category 2 samples\n", + "\n", + " # calculate Z score\n", + " Z = (M1 - M2) / np.sqrt(V1/n1 + V2/n2)\n", + "\n", + " ## Gaussian distribution CDF, pdf, quantile function, etc.\n", + " from scipy.stats.distributions import norm\n", + "\n", + " ## The Z-score threshold under a Bonferroni correction\n", + " zst = -norm.ppf(0.025/Z.shape[0])\n", + "\n", + " # indices of differentially expressed genes\n", + " ii = np.flatnonzero(np.abs(Z) > zst) \n", + " scores = Z[ii] # scores\n", + " genes = np.array(GID)[ii] # gene names\n", + " annotation = np.array(table.column('peak_annotation'))[ii]\n", + " chr = np.array(table.column('chr'))[ii]\n", + " start = np.array(table.column('start'))[ii]\n", + " end = np.array(table.column('end'))[ii]\n", + "\n", + " # create new table with differential regions\n", + " newTable = Table().with_columns(['chr', chr, 'start', start, 'end', end,'peak_annotation', annotation, 'symbol', genes, 'score', scores])\n", + "\n", + " return newTable\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This method takes as input the data table we are analyzing, as well as the column names of the first category and second category we would like to compare. For example, let's compare naive and 5 day effector states:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/srv/app/venv/lib/python3.6/site-packages/datascience/tables.py:234: FutureWarning: column_labels is deprecated; use labels\n", + " warnings.warn(\"column_labels is deprecated; use labels\", FutureWarning)\n", + "/srv/app/venv/lib/python3.6/site-packages/ipykernel_launcher.py:30: RuntimeWarning: divide by zero encountered in log\n", + "/srv/app/venv/lib/python3.6/site-packages/numpy/core/_methods.py:112: RuntimeWarning: invalid value encountered in subtract\n", + " x = asanyarray(arr - arrmean)\n", + "/srv/app/venv/lib/python3.6/site-packages/ipykernel_launcher.py:40: RuntimeWarning: invalid value encountered in subtract\n", + "/srv/app/venv/lib/python3.6/site-packages/ipykernel_launcher.py:49: RuntimeWarning: invalid value encountered in greater\n" + ] + }, + { + "data": { + "text/html": [ + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr>\n", + " <th>chr</th> <th>start</th> <th>end</th> <th>peak_annotation</th> <th>symbol</th> <th>score</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>9772732 </td> <td>9773228 </td> <td>intergenic </td> <td>1700034P13Rik</td> <td>10.0271 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>9797805 </td> <td>9798616 </td> <td>promoter </td> <td>Sgk3 </td> <td>8.74773 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>9859046 </td> <td>9859750 </td> <td>intron </td> <td>Sgk3 </td> <td>-22.0576</td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>10089499</td> <td>10089955</td> <td>intron </td> <td>Cspp1 </td> <td>5.03553 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>20933432</td> <td>20933875</td> <td>intron </td> <td>Paqr8 </td> <td>9.99897 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>23255935</td> <td>23256632</td> <td>intergenic </td> <td>Mir30a </td> <td>9.06698 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>34867183</td> <td>34867587</td> <td>intron </td> <td>Plekhb2 </td> <td>23.9799 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>35890111</td> <td>35890946</td> <td>intergenic </td> <td>Hs6st1 </td> <td>8.13463 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>39478274</td> <td>39479009</td> <td>promoter </td> <td>Tbc1d8 </td> <td>18.8915 </td>\n", + " </tr>\n", + " </tbody>\n", + " <tr>\n", + " <td>chr1</td> <td>40514972</td> <td>40515601</td> <td>promoter </td> <td>Il18rap </td> <td>-16.9661</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>... (26291 rows omitted)</p" + ], + "text/plain": [ + "chr | start | end | peak_annotation | symbol | score\n", + "chr1 | 9772732 | 9773228 | intergenic | 1700034P13Rik | 10.0271\n", + "chr1 | 9797805 | 9798616 | promoter | Sgk3 | 8.74773\n", + "chr1 | 9859046 | 9859750 | intron | Sgk3 | -22.0576\n", + "chr1 | 10089499 | 10089955 | intron | Cspp1 | 5.03553\n", + "chr1 | 20933432 | 20933875 | intron | Paqr8 | 9.99897\n", + "chr1 | 23255935 | 23256632 | intergenic | Mir30a | 9.06698\n", + "chr1 | 34867183 | 34867587 | intron | Plekhb2 | 23.9799\n", + "chr1 | 35890111 | 35890946 | intergenic | Hs6st1 | 8.13463\n", + "chr1 | 39478274 | 39479009 | promoter | Tbc1d8 | 18.8915\n", + "chr1 | 40514972 | 40515601 | promoter | Il18rap | -16.9661\n", + "... (26291 rows omitted)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# get column names of category 1 and 2\n", + "CAT1_NAMES = ['N1','N2','N3'] \n", + "CAT2_NAMES = ['E5_1','E5_2','E5_3']\n", + "\n", + "calledPeaksN = callDifferentialPeaks(table, CAT1_NAMES, CAT2_NAMES)\n", + "\n", + "calledPeaksN" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The score column contains how different the peak was between the two categories. Positive values indicate that the peak is more accessible in the first category (i.e. more accessible in naive). Negative values indicate that the peak is more accessible in the second category (i.e. more accessible in effector)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 3**</h2> \n", + "\n", + "How many peaks in the table above are more accessible in 5 day effector cells, compared to naive cells?\n", + "How many peaks in the table above are less accessible in 5 day effector cells, compared to naive cells? (Save these values as variables, we will be plotting them later)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "ename": "NotImplementedError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-5-15b94d1fa268>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# YOUR CODE HERE\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNotImplementedError\u001b[0m: " + ] + } + ], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 4**</h2> \n", + "\n", + "Find all of the differential peaks between the E5 to E7 (Effector 5 day and 7 day) cell states." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 5**</h2> \n", + "\n", + "How many peaks in the table above are more accessible in 7 day effector cells, compared to 5 day effector cells?\n", + "How many peaks in the table above are less accessible in 7 day effector cells, compared to 5 day effector cells? (Save these values as variables, we will be plotting them later)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 6**</h2> \n", + "\n", + "Repeat this process to find the number of differentially accessible peaks for the transition from E7 to M.\n", + "\n", + "How many peaks in the table above are more accessible in memory cells, compared to 7 day effector cells?\n", + "How many peaks in the table above are less accessible in memory cells, compared to 7 day effector cells? (Save these values as variables, we will be plotting them later)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 7**</h2> \n", + "\n", + "Make a bar plot that shows shows these changes in accessibility for the transitions N->E5, E5->E7, and E7->M. Plot closed peaks as negative values for easier viewing. There should be 6 total bars on the plot. Make sure to label the axes. (Hint: To make this plot, you can make a new table with the values computed above. You can then use the **.bar()** function to plot a bar graph.) If you are unsure of what this plot may sort of look at, reference Figure 1B in the paper for help.\n", + "\n", + "For some examples, try here: https://pythonspot.com/matplotlib-bar-chart/ \n", + "\n", + "For documentation on matplotlib's bar plot function: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.bar.html" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "ename": "NotImplementedError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-6-a392d6098bb9>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m#plt.bar() will the function used to plot bar graphs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNotImplementedError\u001b[0m: " + ] + } + ], + "source": [ + "# YOUR CODE HERE\n", + "import matplotlib.pyplot as plt\n", + "#plt.bar() will the function used to plot bar graphs\n", + "\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## <span style=\"color:red\">Student Answer</span>\n", + "\n", + "*For the next question, double click on the text and add your answer below the question text*\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 8**</h2> \n", + "\n", + "Given the bar chart above, which transition has the fewest differences in accessibily? Which transition has the most changes in accessibily?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we will look at some of the genes and observe how their accessibility peaks change over T cell activation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 9**</h2> \n", + "\n", + "The first gene, Cd44, was stated in the paper to have low expression in naive cells. Filter the table of differentially expressed genes in the peak table called **calledPeaksN** that overlap Cd44. Do the scores reflect more or less accessibility in naive cells compared to 5 day effector cells?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part 2: Comparing Normal and Dysfunction T cell accessibility\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we will compare the normal effector states (E5/E7) to dysfunctional T cell states (L5/L7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 10**</h2> \n", + "\n", + "Run the differential peak calling algorithm, differentiating peaks between normal effector states (E5/E7) and dysfunctional T cell states (L5/L7). Print the resulting table. Hint: Think about the function we defined earlier and what it's inputs are." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 11**</h2> \n", + "\n", + "PD1 protein (encoded by Pdcd1 gene) is correlated with cell death. Look at the peaks around PD1 from the table above. Are the values associated with more or less accessibility in the normal states, compared to the dysfunctional states? Does this make sense, given the gene's function?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# YOUR CODE HERE\n", + "raise NotImplementedError()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part 3: Viewing ATAC-seq data in UCSC Genome Browser" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we will view accessibility sites for activated T cells in the UCSC genome browser. \n", + "\n", + "1. Navigate to http://rstats.immgen.org/Chromatin/chromatin.html. \n", + "2. Select ab T cells. Under the ab T cell category, select all of the NK (natural killer) cell categories. There are 4.\n", + "\n", + " \n", + "3. Search for the gene 'Gzma' and click 'View data on UCSC Genome Browser'\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## <span style=\"color:red\">Student Answer</span>\n", + "\n", + "*For the next question, double click on the text and add your answer below the question text*\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 12**</h2> \n", + "Viewing Gzma in the genome browser, does the naive cell (NKT_Sp) look more or less accessible than the other three activated cell states?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Question 13**</h2> \n", + "Navigate to gene cards (http://www.genecards.org/) and search for the gene **Gzma** and read the description. What process is this gene involved in? Does the function of this gene align with the accessibility trends you observed in the previous question? Explain." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<h2 style=\"color:red\">** Bonus Question**</h2> \n", + "Describe, in your own words, how the differential peak calling algorithm works." + ] + } + ], + "metadata": { + "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.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}