From 120703f0791f776e794042c2cb6160b0995b88e7 Mon Sep 17 00:00:00 2001 From: Charles Yang Date: Tue, 30 Jan 2018 21:59:55 -0800 Subject: [PATCH 1/4] Edits to Lab3 -Added a description of kmeans with links -Simplified the plotting of all clusters by adding in some helper code --- notebooks/Lab3.ipynb | 79 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/notebooks/Lab3.ipynb b/notebooks/Lab3.ipynb index 8aa33e7..4177fa5 100644 --- a/notebooks/Lab3.ipynb +++ b/notebooks/Lab3.ipynb @@ -10,7 +10,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# imports\n", @@ -49,7 +51,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# load in data for part 1\n", @@ -77,7 +81,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# First, select the Gene symbol and mean expression columns\n", @@ -109,7 +115,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Answer here:\n" @@ -126,7 +134,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Answer here\n" @@ -175,8 +185,22 @@ "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" + "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. " ] }, { @@ -236,7 +260,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Select the expression columns for 0 to 100 days\n", @@ -267,7 +293,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Add a new column to our table that holds the cluster label kmeans assigned.\n", @@ -277,7 +305,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Get genes that were clustered into cluster 0. Drop the cluster column for plotting.\n", @@ -304,16 +334,31 @@ "metadata": {}, "source": [ "

** Question 5**

\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": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "# Answer here:\n" + "# 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" ] }, { @@ -342,7 +387,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Answer here:\n" @@ -441,7 +488,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [] } @@ -462,7 +511,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.1" + "version": "3.6.2" }, "timetravel": { "allowedContentTypes": [ From 85f9a55024f137f090b42eb5b9bab3d4029b5ac2 Mon Sep 17 00:00:00 2001 From: Charles Yang Date: Thu, 8 Feb 2018 19:32:40 -0800 Subject: [PATCH 2/4] Add files via upload --- notebooks/Lab4.ipynb | 354 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 282 insertions(+), 72 deletions(-) diff --git a/notebooks/Lab4.ipynb b/notebooks/Lab4.ipynb index 3209389..bfb09a3 100644 --- a/notebooks/Lab4.ipynb +++ b/notebooks/Lab4.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -32,9 +32,82 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
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
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
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
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
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
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
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
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
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
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
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)** Question 2** \n", + "---\n", + "## Student Answer\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." + "*For the next question, double click on the text and add your answer below the question text*\n", + "\n", + "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Answer here:**\n" + "

** Question 2**

\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." ] }, { @@ -113,18 +192,18 @@ "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", + "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 **callPeaks()**:" + "First, let us define a peak calling function called **callDifferentialPeaks()**:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "def callPeaks(table, CAT1_NAMES, CAT2_NAMES):\n", + "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", @@ -195,15 +274,101 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "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": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chr start end peak_annotation symbol score
chr1 9772732 9773228 intergenic 1700034P13Rik 10.0271
chr1 9797805 9798616 promoter Sgk3 8.74773
chr1 9859046 9859750 intron Sgk3 -22.0576
chr1 10089499 10089955 intron Cspp1 5.03553
chr1 20933432 20933875 intron Paqr8 9.99897
chr1 23255935 23256632 intergenic Mir30a 9.06698
chr1 34867183 34867587 intron Plekhb2 23.9799
chr1 35890111 35890946 intergenic Hs6st1 8.13463
chr1 39478274 39479009 promoter Tbc1d8 18.8915
chr1 40514972 40515601 promoter Il18rap -16.9661
\n", + "

... (26291 rows omitted)\u001b[0m in \u001b[0;36m\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": [ - "# Answer here:\n", - "\n" + "# YOUR CODE HERE\n", + "raise NotImplementedError()" ] }, { @@ -241,7 +418,24 @@ "source": [ "

** Question 4**

\n", "\n", - "Repeat this process to find the number of differentially accessible peaks for the transition from E5 to E7.\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": [ + "

** Question 5**

\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)" @@ -253,15 +447,15 @@ "metadata": {}, "outputs": [], "source": [ - "# Answer\n", - "\n" + "# YOUR CODE HERE\n", + "raise NotImplementedError()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "

** Question 5**

\n", + "

** Question 6**

\n", "\n", "Repeat this process to find the number of differentially accessible peaks for the transition from E7 to M.\n", "\n", @@ -275,43 +469,67 @@ "metadata": {}, "outputs": [], "source": [ - "# Answer\n" + "# YOUR CODE HERE\n", + "raise NotImplementedError()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "

** Question 6**

\n", + "

** Question 7**

\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." + "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": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "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\u001b[0m in \u001b[0;36m\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": [ - "# Answer\n" + "# 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": [ - "

** Question 7**

\n", + "---\n", + "## Student Answer\n", "\n", - "Given the bar chart above, which transition has the fewest differences in accessibily? Which transition has the most changes in accessibily?" + "*For the next question, double click on the text and add your answer below the question text*\n", + "\n", + "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Answer here:**\n", + "

** Question 8**

\n", "\n", - " " + "Given the bar chart above, which transition has the fewest differences in accessibily? Which transition has the most changes in accessibily?" ] }, { @@ -325,16 +543,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "

** Question 8**

\n" + "

** Question 9**

\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": 14, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Answer\n" + "# YOUR CODE HERE\n", + "raise NotImplementedError()" ] }, { @@ -355,9 +576,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "

** Question 9**

\n", + "

** Question 10**

\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." + "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." ] }, { @@ -366,23 +587,27 @@ "metadata": {}, "outputs": [], "source": [ - "# Answer\n" + "# YOUR CODE HERE\n", + "raise NotImplementedError()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "

** Question 10**

\n" + "

** Question 11**

\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": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Answer\n" + "# YOUR CODE HERE\n", + "raise NotImplementedError()" ] }, { @@ -396,11 +621,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now, we will view a couple accessibility sites for activated T cells in the UCSC genome browser. \n", + "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", - "![UCSC Home Page](../images/lab4/select_NKcells.png)\n", + "![UCSC Home Page](https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/images/lab4/select_NKcells.png)\n", + " \n", "3. Search for the gene 'Gzma' and click 'View data on UCSC Genome Browser'\n", " " ] @@ -409,15 +635,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "

** Question 11**

\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" + "---\n", + "## Student Answer\n", + "\n", + "*For the next question, double click on the text and add your answer below the question text*\n", + "\n", + "---" ] }, { @@ -425,14 +648,15 @@ "metadata": {}, "source": [ "

** Question 12**

\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." + "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" + "

** Question 13**

\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." ] }, { @@ -440,22 +664,8 @@ "metadata": {}, "source": [ "

** Bonus Question**

\n", - "Describe, in words, how the peak calling algorithm works." + "Describe, in your own words, how the differential peak calling algorithm works." ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "** Answer here**:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From a8a7aab0be7ae65aebf50ce2cf7d732e1857f9c1 Mon Sep 17 00:00:00 2001 From: Charles Yang Date: Mon, 26 Feb 2018 17:45:19 -0800 Subject: [PATCH 3/4] Add Python tutorial --- Python for Data Science Tutorial.ipynb | 2508 ++++++++++++++++++++++++ 1 file changed, 2508 insertions(+) create mode 100644 Python for Data Science Tutorial.ipynb 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": [ + "\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": [ + "\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": [ + "\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": [ + "" + ] + }, + "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 \"\".\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": [ + "\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": [ + "\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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
iddiagnosisradius_meantexture_meanperimeter_meanarea_meansmoothness_meancompactness_meanconcavity_meanconcave points_mean...radius_worsttexture_worstperimeter_worstarea_worstsmoothness_worstcompactness_worstconcavity_worstconcave points_worstsymmetry_worstfractal_dimension_worst
0842302M17.9910.38122.801001.00.118400.277600.30010.14710...25.3817.33184.602019.00.16220.66560.71190.26540.46010.11890
1842517M20.5717.77132.901326.00.084740.078640.08690.07017...24.9923.41158.801956.00.12380.18660.24160.18600.27500.08902
284300903M19.6921.25130.001203.00.109600.159900.19740.12790...23.5725.53152.501709.00.14440.42450.45040.24300.36130.08758
384348301M11.4220.3877.58386.10.142500.283900.24140.10520...14.9126.5098.87567.70.20980.86630.68690.25750.66380.17300
484358402M20.2914.34135.101297.00.100300.132800.19800.10430...22.5416.67152.201575.00.13740.20500.40000.16250.23640.07678
\n", + "

5 rows × 32 columns

\n", + "
" + ], + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
iddiagnosisradius_meantexture_meanperimeter_meanarea_meansmoothness_meancompactness_meanconcavity_meanconcave points_mean...radius_worsttexture_worstperimeter_worstarea_worstsmoothness_worstcompactness_worstconcavity_worstconcave points_worstsymmetry_worstfractal_dimension_worst
0842302M17.9910.38122.801001.00.118400.277600.30010.14710...25.3817.33184.602019.00.16220.66560.71190.26540.46010.11890
1842517M20.5717.77132.901326.00.084740.078640.08690.07017...24.9923.41158.801956.00.12380.18660.24160.18600.27500.08902
284300903M19.6921.25130.001203.00.109600.159900.19740.12790...23.5725.53152.501709.00.14440.42450.45040.24300.36130.08758
384348301M11.4220.3877.58386.10.142500.283900.24140.10520...14.9126.5098.87567.70.20980.86630.68690.25750.66380.17300
484358402M20.2914.34135.101297.00.100300.132800.19800.10430...22.5416.67152.201575.00.13740.20500.40000.16250.23640.07678
\n", + "

5 rows × 32 columns

\n", + "
" + ], + "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\nm786YF+vfbtY67r+Mg8d1eYfJXtb0zApVrwPVuYB06/WFZsggk0gaUqcmCdwfT/X9dZYtpzPnBZP\nGVnWbcuLaR0B67cDvf7ZAnLTMUR/OQztVicjql9h3q5+hoDbl+eQLqd0WPZB+XI9fFmk6TW997Zn\noBMsLvKpl6csb28+5TbxN10TbLmmbW2llmUqn7yXARERFTQGuEQ+ZGMmDpPkMD/RsBuS4O1d0hpP\nWmPfZGsC7jYatpVvRd9O2lTMXmNt8Og9SNKtaKM17mRwMkbrHbFahCfsDWU/HBvBDmRj7O4psoFv\nItNtapR5AxkTOY+l0ZuFvXKVnf7tLRMtX0aeDL7zaQFGg7aiYHrhiYVqojB7VAIS7OkT633THGSt\nEelqACSKAMv8XSwc4zew0zmk12kb+pR5FtavkOndiemWbSTmswUBjuUm0mVt8Pqmw0lI26A2sP5p\nI2328jfY16s+N6iGKuqzt657ycBTDwrU/CaBhqoGT78aPmvmSYuvolBv9X3sVlTfN8KSlqQpk0S9\ntdclUT9MaTN6jfdOC1y/nRj7i6fTXAZf6sSAlzzpYA3StH1FSHzNvF3lfNZjirYf2JfnU26+6ZDl\nbdkHJZ/67kfKNyJN4pj6dIDeW5f51NNVDXsne4/VcoSBv+mulntFNbRUby20dHt7nfNVBkREVOAY\n4BLZpJoaRkMSxiHG1OPzpmqkeodWjkZPbcoiTFcN1oatb9X+xcJ1vgGTZDSe1dA/fT1yWeIlgmm9\ngeVdXiAVu4wT3zOl0Ylo2GmNsQax+FxLs/56QwbiRhqNeURD/g3PPPEYIoJK2eid7Qkifa/HMxqU\n1iDFPt8mJMrli2VN2ulNh5YGkdfZC53KwKCCjq1pWs+PJw8v6uW8d1+gcrKlw9iGnUarPOqvzwfW\nF3/cib2eRalATKwTnm1tlMdKrDfmC1i2000Nct9y8+F2G6jhvaKgMKm2kQ9/Q3zt61Wfb4zWAwyf\nocLedSatSBaBTmXEvKbSoMrsRX/XTbpKf1PEGtOMMnvNT7BTJOqtsd8uwqQptT3r0OtLmqi3aej5\norFe41jgpa1DzJe01ZQ+Vb+T0g9q8zhTdd5zHe0mJMhA2lYW+j6QhvQD2kyCcUJCrNNTN7z7WaKn\nDhnHMnO5qXxZys03Hdp+bNt/LNvEryz9uutOfQMcr9zm0+l4Io+D/qe7Wm7lK1FD/GM9phjpHq2G\n9eenDIiIqDAwwCUymT3Ke2a+54vWwNHcA9vX08hvip5aY9cICITm//YEvd4GpQpKBN9r40y9K+r6\nSNlg8htIhEQ1zmRD1hZINBwk1yMDI9M8lkBJBDdP641xT4PP53o81diz39BGm890zaa6LlBrYJrS\nUaW6LDvbiQQfetBh/67R2xLw2kB7eo3yHWTdBnogYmKkVzRivdtBlMc95gaxKjd7uoSGPWW5mRrO\nQa9jDGEbaENQBdnAtuXDh329PuWhN+i9PbaSDGpFGRl5UnU38DWdIaTf2J4Bb4JUROqtkVbbOipW\nq639K4Nb/9cyG8GmLX2qzAOe7DBOPHjmkScGTNtE0XuXzUz7iqlu6PXRWx7aTZ58yk2eMOurHbs8\n5eaTjstRXZ48sPVWerdJAEbvbc9A9chlPv0cT/xOd11+ev7MJx+y50+ypTsfZUBERIWCAS6RH/Yh\nxt4gSA5n7eW59soz9HDrPmRqb5qijdZj4l2GJzgWDS/PtWfNu+k9TRrvMr2BRhh4eui6+W94BZpH\nNcYNPkOi/dzQRp/PdL2jCsqsN5YxhgGbhmFK9hsaqeDEflMaY/hnoOHZPumVPUSmbWe89JMa9vQG\naYyrcpO9RXfbl2kbCumbDps8bIPAgYLOvl7fdHh7VPXrYUXa7cMsPdd0qs9OQki/vzpjUVTqrZrP\nvg59GPCt1uHN9mX6S59PsO1A7S/eeUQw77me1vvSjz0O+bLtK1YquLcdx/SX7ZIJn3ToJz/03koR\n4Mnv2IY0O1M9qAF7byWX+VTp8smnv+lulyvyV0Oeu9i5X+VpE2bLeSzpzmsZEBFRYWGAS2TTsoHe\nIysbL4Gv7/TPOkzZOzzZMzRUo3rKbEMbjUAjr+u28GmgOgg0j60xrg/r9AakzkGmEbh6h3/qgYMt\nIDCGg1rKxAgevEGGb1Cm0084mIIRB9b0yuDW4ZrnTqP1xqopvVoa7IG3YEmLKjc37OXmIx/bIBD7\nvM5lZtRDU6Pd1GDX8hxsfSGk382JiaJSb/V1mHt0JdUza7ue2meZftLnrz6bWfcXGZz5XictT5a9\noY0eMe0rWhrs+5lgTosKgt2wpsNL7630Dmn23IPAj+z508X2uBVvBBxxEEI+/aTLebr75UraqBJ1\nslJPt/PJpFDLgIiICg8DXCIzOST1tSGentXZ07wNfX04rSSH9umNG+vLNDzN0zu7CNMnf6P15MhG\nrbWhbFDD57SXun5QMK/73BANQ20IqNEYt1+P5yfYUjdk8QauDoGD5NiTpdZhmtc5oDOug7MGGVa2\n9Kr1ea+ZVK9BsA1XNYaW2qneHFtafJZneunDV33Lzb3g28A/+7zqsyoz/W6z1hv3aI12eV2i5zpj\nte3ylHbJnn5/QXY4have+p5s0Rg9s7YhxvZ8+Qu29H3BXp+t9PSpfcDTE2y+Tlq8XovGXtt+pafB\nzigPa1p8lmd6GcPyLelI8b3DsHYPAO2aYtPlGD70/aZloN54KdR8mj4bHKeHsFxJH34ur8d36L3N\ncxkQEVFhYoBLZKIPL/RewyfPzBs3XKl4bVt9mgxaPcOIRePRGPpmGdpZGdfeqAfESQsXab0n9kat\nHmDI75qDDDVETvIMec4HdZ2qNVg20qzWa8wzynoXYU+vh9HA82nYO1zHKBuA6q6y3sDV+ZpLPQCw\n92TZe3X9XCtpDB0N6TpGnfdaUMnbq+udT6XXfDMprTzUfEba1LXW9hMRnu1q1Ac/6bBwuw2M8gm0\nLIN9vbbPekM+DZNes6ZfD+oMLtfnOv3WINuvIlFvVVrtAZNjz6w9X35O6vjZF6yc67z1plSmfHrm\nU2mwBVqem+YZaascjTbakPRvrD2OKnjz9t7b0uFY3qK+a73G/hm9t977FgTmOp8+Zehvui74chWV\nz/TZDr3OeSwDIiIqXAxwiZyYH/djNLJN0zzXK3ZTjSQRqNmHsXkDYp19KK5xQxf9JlNyWfrLuMlV\n4B4P1di3Xy9pZ6TZcp2onuaWA4foAYAnX+Zr8ox8mRp4/oaEGtehyZcIEvQh3qbeIvu1iYre22Lv\nRbP16vr5rjEc1LlHXLGnVwWk3m0nX94hy9Z11hf5MG8XVR4NYjHUdIMx7Vpr2zW42nV9Yj7PTX78\nlZuZ223g2Ovth329PuWhRhnY0q/VP09wqJe/XmbWRr2F2/S7CfalolBvfU626Bx7Zn3y5fxdzygC\nW322sJ+8UQGpJb2efDqsU+RD3izPmNdzl2mjPDwn32zX4GoBvpjPuBGTTzqcyttb3x2fa6vu1hy0\n91Zym09/dcjfdNflp2jXb+t3yPZJd17KgIiICh0DXCI/jDuPmntxPUM4LUSj0OlRPUbDSuMUjOlD\nk7XrHm3ksNfAd1F22bMmyDTb12FfvpxHf/SJlz6kzzvs2rdhL9JvKQtZDl+ib21rz5XPtYka514q\n+zqcv6uC4yDDXB3Ta38EkQxE1TSjZ1dfZ230NR6PY5B3LbbdhdVvuZnmcwyIHORtG/jnU5baZ3NZ\nmm6WY2a+O7O5Dvv0Rlq5Sb+rYF851/XW3xB6x55ZLV++N0az59N3GziwL0vbTvZHEMk069M8PZPa\nOsX3nh5nLTdZx83bQNCG1dqPY3K7+2wr63HLqby15dv2C10WFr+WoD3ay3tSKBCX+XRIl8bfdLfL\n9VB3SRbzOPU6h1YGRER0LlxwVlDvI0p2tnnQHUWiihVDa06cPHlSvSsspmFwbAARERV9WYswKjZB\ne/514JOMRERkKFOmjHpXNLAHl6igqJvWSD5DFYmIqIhRvc5+em+JiKh4YA8uFVtFtgfXdMManRwO\nZx0iSERERYVptI0gh8Lrd0AnIiI32INLdF6pjyEJDG6JiIoudXdrQV7DzeCWiKh4Yw8uFVtF/xpc\nIiIiIqLIxh5cIiIiIiIiogLAAJeIiIiIiIgiAgNcIiIiIiIiiggMcImIiIiIiCgiMMAlIiIiIiKi\niMAAl4iIiIiIiCICA1wiIiIiIiKKCAxwiYiIiIiIKCIwwCUiIiIiIqKIcMFZQb2PKNnZ2eodRaqK\nFSuqd+6cPHlSvXMvdXIvPLFQvGkQi89fuxWhrbEo2YSEbmMwu9NoLBzUVE0rDPp69w6Mx4tdKqtp\nxVE+8pGSgE6jFqkP9TEkYRxiwloUDmnLWoRRs6/EiwG2taduB9Gy2G87IiIiKkhlypRR74oG9uAS\nnQ+y9mOv+Kdl9cv1z4VFrbdGtWIeIOU5H1lYPM0IbqXaqBHuorCnTQa3sQlAwG2dhb071dsgiv22\nIyIiovMKA1yi88GBfUhCfbS5tnCDlez1K7X1Vr9CTSim8pyPrGQkbtV7QRd+86V4xaKh+lO4+KTN\n1baujJjXZHqMVzyGNJDTb8Ubnmn6K7a59gUiIiKiYoEBLpFBDiXt1svzSkhR081k75jn73JoqDF/\nAlLVLLJ3bPHT3uVor8mb1N8Uy3Ls85uXFYRKs2NaTbL3ye462XvoL80mtnLo9PQiOA74dzFfZnqa\n+L+t19L+PXvZGOzzOaVXm2cEFmfpQ26DLtOF7PkjvMtReQo9H2qbxiaIYBNImhIn5jGl303eVB2x\nb1s9n975zWnT/qYNh07DpFjx3nU5HES6CMTR6d+2AFyvL6PmiwL2pFlft15O9nSr+mVbr2XbiFew\n+kpERESUVwxwiQStse65TlI3e1TgaxRnjxqD2eq9JzDQgpI4TJLBgtnCMQ7BgG72KPv8i/CECtqC\n0QPXYD2LWVi/QgRBDXZiurwOV03V1mMLSr0BksnWBNydp/nUMFhT0OT4PVk2toDIaXvo5WItw9Q1\nYp4GQKII5izbSiwzL0GUTN/dU2TAqGh5SkCizEeDaqiiT3WRDxUwmqnvu82b3jN7K9pYelDtZWr+\n7Dvs2PWQdH9D2I3hz0jGKCPNal1anTJtW42av2dr49pfPeC170dy32KQS0RERAWBAS6RaITPNoIa\neTMpNTTz84H19Wl+mYZzajfzycLi1/QeO8vfEmLRUpsmghjHHjV54yH7vGmYNDt471vFLuPE94Ld\ntEgFW1tFHj1DZdWQ1K0rsd4IpFMSVCBiHqZqzJeA2UZA4nY+tV5P0GR8z1TG8vVGJzFt4XRvQJ+1\nCG/K7SFviGWaT98eO7HXE/irgE7kK8m8zBdv1f66d5+LMwRmTumT22PrIsyW5Vf7Sv0mY67y0RSx\nRpkY88mblLnOm+qZNQXVOluZWj7LYcdqnWr5bm8OpQfTvtfbGtNnT0lAjRdVerW6bk+HooZHGydc\nUifrJ1S8Q7TlazR6immzp/n2+BMRERHlFwNcopR1nl7Nnvd475RcscsQPVjwo+XAbrbeK/16S6nn\ni6ZrLSvfiqFGsLxwnU8vbsuBQ7wBapB580T1qsmgxxvwiGBI5FUG0ukH5GfjZkgyaDVfJyrme1oP\nuvWA0e18gipXPWhS35PBnu1u1A17yu8Z6RBEGbzoCaS89KG4Zipwty/zimpaOkK7OZIpX+ZlmbaH\n3isZQj6M9BmBseQ6b5uQKINo83clrUxN19daylhQddDbg+qOvn7fkQBGunqK4NZyLa59vYreo94W\nWvJEMD9d5MH3LsxN0VOW6dZ9yFRTiIiIiMKFAS6Rh72BXxk1aqu3DnwCKK33SvINFCpWMxZk7aWT\n7MsJNG+eqF61IT0DBD2emyHZgnap8pWood66nk+wDJ82gn855Nd0Lab2UtepepmvE/a+9F5j03Ww\nKsgyn5SQ8nRDqED50uQhHz7DdSWXeXP8rlGm3vl8hqjbelDdUT3hRmDqYUyPRU/bjab09d7qPHxa\nBeVG769+/bE1v5Zh4ERERERhxACXKMJZetVMLMGRCs4dez3NvXVu5xP0IbZqvZ7gPxgZAJqvE1Y6\njdaHAJuG7PoEd4re62i7IVQwAfJlWZ7rfBgBnjl9IeTNMUg3rqX2zmcpY0ErE4dtHZhDT7NGDUO+\nMdo23TcdGuMkgRq2bPT+EhERERUmBrhEHubhpZLvTXsCUkNjfZdjBGOSb+Blv1Y00Lyh85cHdd1x\n0GDIGLobrFfQPp+1N88gh7p6r8W0vrQhsEavrH2+QfAZsmsP7nRqaK/95kd5pYbZ2oO5oPkQfALt\n/OYt5RvtZmTegNNexirw9AlUg1Dp8rme1rjBlE/Q7xz4ps6WPdj2xxOZr9O2v8L/yCQiIiIiBrhE\nzf+t3fRGmj3Keyfb7PmTfO+GHEjlaLRR1+yal+O5aZLkEHglTZnke4MlKSxBmuqdM99MSgajT6ub\n/xhBigrOLenW5lN3eO7UV79O2O18tt48o4ztNxbyPJLHdvMta9Dv7fn0BmF+rlFVQZlPsBaMkS9z\n+sS2GGUMOzbW4zofKvh02IZ5yltKgufOy56A017GRuAZYt6NEyo+gazWW+1wYsPWUy/Ju0rbh1k3\nbC2v8V6E6fIRQx6yrujDlHkXZSIiIioIF5wV1PuIkp3N+3NGuooVLaFNUCdPnlTvfMkAJeB1gcZN\nhUxBj8+NdyRzUGRnvjFRoPk08s7Kge6OrILK2qN9blhkoa1npVh3GpJkAGpmu1GSN0ixs95QytV8\nKiAzl5Hf71nS4WcYr+JZnio/eWdf8zbQtyNMZaeWZ8urE//5EkGj6UZJrvKh0ifvWu29wZLLvPmZ\nr2WD+mIb1vZfxpY6Zb8JmH96fnzn9zfdHGx71RfpE3XMUh/959f3xlNERERUXJUpU0a9KxrYg0sk\naI/bUY+XMchGuHZtZCi0u+SqR7WYyce2+AmwZIBiXY8MKtw9+idYb51+LWdt9DUeH2NwSE/DQb6P\nRtIf72INcNzMp/cK3mq5CZHf71nS0RSxnkclKTJwVNOM3k9/N5LyGRZs3EHaxbDdhoMcykirE9Zh\nt67y4XhNr7u8afNZ6qKsD1+ib22RN59rkE1lbBpB4HN9rF+qp9lnfv890Ggea62vspy+6YsaPvXR\n9KgkD/2RWAxuiYiIqKCwB5eKrXD24BY6U2+buZeTCkBKAkbt68agioiIiKgAsAeXiKjQZGHxtJ22\nGx8RERERUaRigEtEESt1chzS7wk23JuIiIiIIgUDXCKKWPJ6WQ7/JiIiIjp/8BpcKraK9TW4RERE\nREQRgNfgEhERERERERUABrhEREREREQUERjgEhERERERUURggEtEREREREQRgQEuERERERERRQQG\nuERERERERBQRGOASERERERFRRGCAS0RERERERBGBAS4RERERERFFBAa4REVVSgI6devl8OqLgU+M\nw+yV+5CrZg1V9vwRYjkJSFWfXTuTgx3zX8PsTepzEZLnPBVlYS5vvYxGYHGWmhDhikqdyF4/FQnf\nmQpd7dsJKerz+STcedeWd/7UaSIiCo4BLlERV6XRzejT5Vbvq+3ViMrahISJQ/Dom+uQfUbNWBiO\nrMInUwp5neczlncE2ITZL32DvXk9G0VEREQhYYBLVMRVv74n+g+M9b6eGo13PknAq50qIH3ZJLxp\n7hkiIirKmsdi4TdfIra5+kxERBRmDHCJiqMSZdFs4DD0L38aSdMWYYearDmThY0fjMHAu/Qhzb36\nj0HCkl3BhzMH+54cChibgCTxdvYoOY9p6Gde1ynl7MKyd4N89zcX89j4G55qn2583ng4GTOe6Y/b\nxfI73TUE8fP15WcueQtP3NtXzNMXdz8zVcynf0+yfPe5WPSS3+3VH09MXIT0HDWTJgfp89/CM/3l\ncuTyY/GMmGfHb+rPTgKVdx7Kw+KgN6+336vnNcfeS5zHbeq23F2Xidt0mLeB3H7LsvCn+lNQ4ruz\nX3rasw65DR99zrqtpewNU/FSrKojxjyBzi9lLcKobmMwW7xNmhInlm0bSpu7D0nvjsDdveR6+2Kg\nwzr1YepGHdS314RpycF79Y2hu9t3YfHEIflbx9apeEB81zqsOA0z7pXlYNvW2rxxmLdHfbazD1EO\nJZ3iWOGZR5T/qGlpzvUxaJkdQ+IY+Tfb9shehQli2bc/swjZahIRERU/JV4Q1PuIcurUKfWOIlXp\n0qXVO3dOnz6t3hUTmcmYtmw7rmzRGe3rl1UTTf5xCS4+vRzzfspG/Xa3oO5FYtqpTZgR9xxe31IK\nHfv1R/9OrdDggk2Y9fksLDvWEDEtL0cJOVvaD5i9oSJi+kbjMrksN9+7sCKaVvsbu9bvQqN7RuCR\n2xuh1pUVEeVynY5yNiFh8HNI2Aq06N4PD/doiSuPJOGLrxYgrUJbtK8n8i3neVzOUxYd+8vlR6t5\nvsLKAHnyyaPiPN9WbE1cjuNX34uH+/4bdQ6JYGnhUhzcnYT3V0Wh+4P3omuTf2L30kWYsaEUOtzW\nAOXs321wN/7T9wY0i9qHZUuXYv7RmujZupqWtuz5L+D+KbtQN0bMc+etaF/3b2ycPxtT13uX5cNf\nebssDyd6ench+cfVOF7nLjzWvx2anN2OGV/Mwo854rst1HfzsU3dlrurMnGbDhmYPDQRX2VXxd1x\ncejbohRSp09F4uFTOHCoqk9aLHLWIT52POacqo2e/R/AXR2j0aT8MWxeuQpzEk+hdZdmqPQPEYuK\nQGzwC98BzXugf/9u6Nq0Ig6s+QofzclA026tUOWfanlmJcqjSoPyOLFyM6JiBmF431aoU+NylBMB\n9TSxb+9Y+wN2XdQW997fAzG1T2Hz8qX4wlS/RISMZS/E4bnvc9C0q6ibPW5Bs0oZWDt3FqamlEf7\n9nVRzt9pau34sRn7N3yHHWVu1tbRpurvSPtxeejrEAVweO5SJJZvju7NL9G+hawkzPoiGQfO/IY6\n13VGgwr65B3z38Cs/W3R/0FRbvokK3Vca9T+LkRXMT67SOcZEVAPegbv7SiFG++OxX/aN0DOsnjM\nSz0jtjHQqtvNqKsdJt2UWSnUaFQOaYu+x/y9VdGtXU1EyaB3wguYmtUcz45/APVD+3khIjqvlSxZ\nUr0rGtiDS1SMVapcTfx/F9IP6p8zv/0AnxxrhRcTXkNsFxFsXXsDYh55DZ8PvwEHF36Axfv0+exc\nfa9iLTRrXktrtFZpEC3mqQXZnszrOqXMxR9g9uFqiHs9HsPuuVl892b0HP0anm8LbP9+LdLFPDtm\nTBTz1MeQt43ly3ni8U7vakgPsnz3jqHK7W/h1UduRUu5/JH/QVfkYNkv1THyrafRtW00WnYZhKF3\nVgb2rEWqpWfJ/F0972M7lUTusk2qZz0L61ekAR3i8PwAOY++rFcf+zeisv+H1AxtJl9+yjv/5XEa\nde58De8M76an9zHx/h7x3fnTsUz1ZuVnm7rjrkzcpmPHnAQsgyiTt15Dnw6irDr0xbC3YlFjX/Dh\n+9nr1yLlH/URN24EesrvynUMGI0X7xf71uFfsf2IPt+ONYuQWVssd3hPtBfplet4fkRP1PnHJqT8\n4ufkWanKaHhtfcg4rlLNpmLZTVGllP4nTasheGN0X215Le94Gs/fLda5ZxU2qvznrpmOSSmXI/ZV\nY/+IRvt7RuCd1/uizpZPMGd9sJN2OTjd/GnPOuR3x95fX6vDRs+zq3WUuBrNWont8ctOT89mzi/J\nSCpfAdWjspC60xiusA9b1uSgSnsRyKsp7gRPZ86y6fjkcAX0fP41DLlD1IW2tyL2tdfQRgS+Zq7L\nrPKtGDpArGNDPD5JzNGC5QkbgK5DH0ebivosRERUPDHAJSrGylYUAZdHFjauFC3+GhWR+2syNq73\nvlJzolBdND6TUpwa/Hn9npSf7x5D6nrx3Qa34vqaapKmLFo+NR2fv9FNfD8NSctE47nt7WhfVf1Z\nqX5bV7QRy1+cqKKcfKmFNteayrJUGUTJf6/9N5qZOs+r122q/Zv7t/aPYvuuUKV6LfH/ndirZb0i\nqlxRElgpGugrdyFbjamMavs0vv5stE++AgtHeTRF11vkiRGv6m1vQjOx7MQNx8Sn/GxTt9yUidt0\niKBqvSiTVrYyKRuNmK7W7eKkYvvHMWXWOMTYZq1Su4n4/zHk/qF/rni5KLOd32DGnE3INAYI1e2L\nd2YloH+LvJ257tpeBPTqvaSv03vCKjVpFXLLXomoo9b8bxR/r4TTmJfyqz5jAG3aRFvWUbFabfH/\nNKQf0D+7W0dJNGoRDWxNxhY1hHzvr5vE/tEXfcUukfjrTn1i1mYkZZREmxYicAxR4HSexpYUsb6q\nnRDT3LRDlqiM9t1vUB90oZRZxU5DMKQRMO+DpzH83WRU6vA0YtuYlk9ERMUSA1yiYiw7QzUsNQeR\nLj9u/wYvvTQOz5hf7/yg9SZuPKBazhZ5/Z6Un++mY+928U/tK0W448+fOCEa1HWqiwarmuIhgnvZ\nM7bjaDiulhMBitOYW/uQmxJOgYyf73qURLM+cYipsA8zJj6Nu3v1xd2xY5AwPxnpga7BdRSO8rgS\nVewFXrUW6op/0g/KgDE/29QtN2XiNh3ZOJjhXCb6CAeXTuUgUwRwG5fMxicTx2DguEViYhYOquKs\nEhOH2Lo5WPzxGDxwl7wW+GlMmCbSkZ9YP2C9yUKmHMIgh1Db8//SdCTKWfbsD36taJjWUbZxNFpC\nlM8m2QO6D9tTTqN901Zo2LwWclNEICoXI3t10QrNrpZfDFHAdGbjqNzU9arhcn2CR9SlFbV6rwu1\nzESA/ER/tDychR0lb8CQAdYgm4iIiicGuETF2NGD+8X/66P6FfpnTafR2l1KnV5fD9R7IB3l9XtS\nHr97OtgdiyJFVdF4TpiOLyeNwJDbm6LG6V8xe8o4DHxwBBb7G6J8DpQtXUa9E/JTH9xwWyb5SEfJ\nKBe9cTlpmP1EX3S6qz8eePo1jJ/xA1JPVUbX9rZll62Pnm9Mx9fvjcOwfjegecksJM6cjEdjY5GQ\nYrmjWHg1iMXnDnnXXq/eGuDkUAjcrKNyE7SsCiz++VfgsOyprSUC2bKocnVTVMnYgO2HT2PLhmSg\nRTQamYdhF7RSZbWh+xYhlFnutq3YKN/krEViQW5HIiIqNAxwiYqrM2lIWiIaZDVboZk2vLIiLpdD\nNFVvint5/Z6Un+9WR51G4p+dvr1Q2QtHoFf/yUjKuRDlygM70vf73i01OwuZ4p9mV9j7dMyycNTW\nS5p5YJd6V/jK1o5GzIARePUTESi93Q8tc9MwY7H1GsLA8lsekm+ZIGMXZGd6jcqy6Z+fbWpwX+7+\ny8RtOvT5nMrk4L6t6p1/O2a8jITttRD7WoIIgKbj84R4vPr8IMT8P3XXJJuoqvXRvtfjeD7hE3z9\nydPoWf4YZn+djPCHRhVRSW7KrVuxvcDumRjKOqqhUeuyWm/tDjF/UvmmqCu3T80GaAkxbecmbFwL\ntG8b7Rtw5ptK57Z9sI8dyN23T+vN14VYZjnrkPDmKqDtIAxrC8x7M0Ecc9TfiIio2GKAS1QcncnB\nxikT8MlvJdH+jrZqiF41tIypJoKVb7B4g7WVlrthMh7o1R/xa5xab3n9npSf71ZAw2vFd7cuwo/m\nR4qcycL6pWnIqVwLdcvWR8v2orm88msss/V0pn87D4liGS0bO19nGVVW3nt1K9LNl6TmJCNxZbAb\n84RZbjI+ie2PgR9YA1k5tNLxLrMB5b08vJKx2LiblCYHqV99g41oipba9Y352aYuy91VmbhNRzU0\nbyuCUXuZ5GzCYsszYJxkYfuvYhm1W6GNcRtgSe5fa0S05pGFZWNi0WvUD9ZAtnxlVAx/NKeURLM2\nNyAKqzDPng9RJqO69cUTc/J7sia0ddRpLubN2IDpi0XZNG+A6nJiqQZo2AhI/HgqEnPro1njgiiQ\nkmh07b/Fum11QRwrls0zb6dQ8pODpMmTMA/RGDbgZrQfEIf24nsvTV7n/OghIiIqNviYICq2zpfH\nBP39xykc37kRGzck669l8xD/3/cw59dTqN5pJF68s6bn8rVyNa7EqRXfY/bCBdh8siIu+2s/Ni6a\nhrc/Wo2DdftjWL9G2mNF7I9scfs9nMlA0px1SP6tBK4sUxoVrhQBidvvOtDXOw9T5yXhlFheiWPb\nsfzNcXhvW3n0eWIwWl1eApUa1BXzzMFHX3nnSUyYiFe+z8AVnYZjaIzzY4KiRLxy4NtV+GpDKkqX\nLY/TO5dj6sSPcKhKXRw4ZH9MkPkxI1IWkqevQGq9dri3palHVNsm2Z55nb9rm17+UlyYuRBfzPsO\nm/dfgBL/PIXfUldjxv99gsU5dRE35C7U8hcTOJT35S7Lw4merjMokf4NEveVw8XYg7UJb+H1lb8h\neuBIPKjuqOW6PjhwVe4l3JWJ23RcXKeWXibfiDIRx4USmRsxY/xkzDsk7wZW17OtfZXFBQe+w7er\nk7F5bxQui8rB4VSR3jdew7Rt4gfyr7/RQHucTVlU+GMt5sxfivVpJ1HiH2eQs2cjFie8h6k7SqHP\now+jpairzo4jbcEP+HbvGVx5WUmUvsT7mCDPo3IMtkfolLiiNipt+g5zvluEtSp9aWtm4b3X5yG5\nwi0YMfhmMU19187+OB5DftZR4TSyv5iHJZl/o+VtD6JDPTkWuRT+3rcAs9YdwYmanfHQnX4ee2Ww\np8tlOqOq1RPpXCC28SocOF0K5U7t0o8VW+Vx/RLPPug2P7mJkzH4832i3j+H/k3FF0vXRKMyKZg1\nZxFyanRCyxq8GpeIyK2i9pggBrhUbJ0vAe6JQ7uwOW2795WRg8vqt0Lfgc/gqe61rcFM1OWI7tAS\nV57Yj6QfFmDOUhEcZZxBg46PY9yTN4jAQp/NHgy6/R4uvBRV/t6C71eswMJle3BVx5tRq4LL7zox\n1ns8FYu/+UZ8dyP2XtQKD49+Dj0bqgv55DztxTy/GfP8hK2naqP3oyPwZK96npvC+ORJNFhbRpdH\nTvIq0dhdimWpv6NRr+cw5LpjmLEMnvmcg9QwBrhlS+Cy5jejxYW7sHHVcpGWFViybityq3XCiLFP\noFWgDld/5e2iPJzo6WqKEW92wm9zp+KjeauxMedKdB38HJ7sKMebKm7rgxNX5e6yTNymQ9WRyzJX\n46v532P+uu2Ian4vHmt1Ast+MdUJB5WatkXTUzuwdtX3+HrpKqxJO4UGtz2KkXFNcejrddhV8zrE\nNCyP0vVuRvsrDyFt1Sp8/f1SLF69CftLt7DWVUeX4NKKGUhbuVQsfzVKN++F5mfdBXX4R1nUbd8B\nTbEXmxN/wBffr0Di1t9Q5dp7MfK5u1BfPvvaH5eBY0jr+GdF5KZ9hZUZldG9f0/Ps28rncnEtBW7\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": [ + "" + ] + }, + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
diagnosisradius_meantexture_meanperimeter_meanarea_meansmoothness_meancompactness_meanconcavity_meanconcave points_meansymmetry_mean...radius_worsttexture_worstperimeter_worstarea_worstsmoothness_worstcompactness_worstconcavity_worstconcave points_worstsymmetry_worstfractal_dimension_worst
id
842302M17.9910.38122.801001.00.118400.277600.30010.147100.2419...25.3817.33184.602019.00.16220.66560.71190.26540.46010.11890
842517M20.5717.77132.901326.00.084740.078640.08690.070170.1812...24.9923.41158.801956.00.12380.18660.24160.18600.27500.08902
84300903M19.6921.25130.001203.00.109600.159900.19740.127900.2069...23.5725.53152.501709.00.14440.42450.45040.24300.36130.08758
84348301M11.4220.3877.58386.10.142500.283900.24140.105200.2597...14.9126.5098.87567.70.20980.86630.68690.25750.66380.17300
84358402M20.2914.34135.101297.00.100300.132800.19800.104300.1809...22.5416.67152.201575.00.13740.20500.40000.16250.23640.07678
\n", + "

5 rows × 31 columns

\n", + "
" + ], + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
diagnosisradius_meantexture_meanperimeter_meanarea_meansmoothness_meancompactness_meanconcavity_meanconcave points_meansymmetry_mean...radius_worsttexture_worstperimeter_worstarea_worstsmoothness_worstcompactness_worstconcavity_worstconcave points_worstsymmetry_worstfractal_dimension_worst
id
842302M17.9910.38122.801001.00.118400.277600.30010.147100.2419...25.3817.33184.602019.00.16220.66560.71190.26540.46010.11890
842517M20.5717.77132.901326.00.084740.078640.08690.070170.1812...24.9923.41158.801956.00.12380.18660.24160.18600.27500.08902
84300903M19.6921.25130.001203.00.109600.159900.19740.127900.2069...23.5725.53152.501709.00.14440.42450.45040.24300.36130.08758
84348301M11.4220.3877.58386.10.142500.283900.24140.105200.2597...14.9126.5098.87567.70.20980.86630.68690.25750.66380.17300
84358402M20.2914.34135.101297.00.100300.132800.19800.104300.1809...22.5416.67152.201575.00.13740.20500.40000.16250.23640.07678
\n", + "

5 rows × 31 columns

\n", + "
" + ], + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
iddiagnosisradius_meantexture_meanperimeter_meanarea_meansmoothness_meancompactness_meanconcavity_meanconcave points_mean...radius_worsttexture_worstperimeter_worstarea_worstsmoothness_worstcompactness_worstconcavity_worstconcave points_worstsymmetry_worstfractal_dimension_worst
0842302M17.9910.38122.801001.00.118400.277600.30010.14710...25.3817.33184.602019.00.16220.66560.71190.26540.46010.11890
1842517M20.5717.77132.901326.00.084740.078640.08690.07017...24.9923.41158.801956.00.12380.18660.24160.18600.27500.08902
284300903M19.6921.25130.001203.00.109600.159900.19740.12790...23.5725.53152.501709.00.14440.42450.45040.24300.36130.08758
384348301M11.4220.3877.58386.10.142500.283900.24140.10520...14.9126.5098.87567.70.20980.86630.68690.25750.66380.17300
484358402M20.2914.34135.101297.00.100300.132800.19800.10430...22.5416.67152.201575.00.13740.20500.40000.16250.23640.07678
\n", + "

5 rows × 32 columns

\n", + "
" + ], + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
diagnosisradius_meantexture_meanperimeter_mean
id
842302M17.9910.38122.80
842517M20.5717.77132.90
84300903M19.6921.25130.00
84348301M11.4220.3877.58
84358402M20.2914.34135.10
\n", + "
" + ], + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
diagnosisradius_meantexture_meanperimeter_mean
id
842302M17.9910.38122.8
842517M20.5717.77132.9
\n", + "
" + ], + "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": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
diagnosisradius_meantexture_meanperimeter_mean
id
842302M17.9910.38122.8
842517M20.5717.77132.9
\n", + "
" + ], + "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 (, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"\"\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": [ + "\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": [ + "\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": [ + "\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": [ + "\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 +} From 24b6a7d6ded7d0b02d880e90d5d14e4379ca02db Mon Sep 17 00:00:00 2001 From: Charles Yang Date: Wed, 28 Feb 2018 18:31:58 -0800 Subject: [PATCH 4/4] Add files via upload --- notebooks/Lab3.ipynb | 1052 ++++++++++++++++---------------- notebooks/Lab4.ipynb | 1384 +++++++++++++++++++++--------------------- 2 files changed, 1218 insertions(+), 1218 deletions(-) diff --git a/notebooks/Lab3.ipynb b/notebooks/Lab3.ipynb index 4177fa5..83a2ec7 100644 --- a/notebooks/Lab3.ipynb +++ b/notebooks/Lab3.ipynb @@ -1,526 +1,526 @@ -{ - "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": [ - "

** Question 1**

\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": [ - "

** Question 2**

\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": [ - "

** Question 3**

\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": [ - "

** Question 4**

\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": [ - "

** Question 5**

\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": [ - "

** Question 6**

\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": [ - "

** Question 7**

\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": [ - "

** Question 8**

" - ] - }, - { - "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": [ - "

** Question 9**

\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": [ - "

** Question 10**

\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": [ - "

** Question 11**

\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": [ - "

** Question 12**

\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 -} +{ + "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": [ + "

** Question 1**

\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": [ + "

** Question 2**

\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": [ + "

** Question 3**

\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": [ + "

** Question 4**

\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": [ + "

** Question 5**

\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": [ + "

** Question 6**

\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": [ + "

** Question 7**

\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": [ + "

** Question 8**

" + ] + }, + { + "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": [ + "

** Question 9**

\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": [ + "

** Question 10**

\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": [ + "

** Question 11**

\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": [ + "

** Question 12**

\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 bfb09a3..f833bfe 100644 --- a/notebooks/Lab4.ipynb +++ b/notebooks/Lab4.ipynb @@ -1,692 +1,692 @@ -{ - "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": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
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
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
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
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
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
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
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
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
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
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
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)Normal T Cells \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", - "

Dysfunctional T Cells

\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": [ - "

** Question 1**

\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", - "## Student Answer\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": [ - "

** Question 2**

\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": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
chr start end peak_annotation symbol score
chr1 9772732 9773228 intergenic 1700034P13Rik 10.0271
chr1 9797805 9798616 promoter Sgk3 8.74773
chr1 9859046 9859750 intron Sgk3 -22.0576
chr1 10089499 10089955 intron Cspp1 5.03553
chr1 20933432 20933875 intron Paqr8 9.99897
chr1 23255935 23256632 intergenic Mir30a 9.06698
chr1 34867183 34867587 intron Plekhb2 23.9799
chr1 35890111 35890946 intergenic Hs6st1 8.13463
chr1 39478274 39479009 promoter Tbc1d8 18.8915
chr1 40514972 40515601 promoter Il18rap -16.9661
\n", - "

... (26291 rows omitted)** Question 3** \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\u001b[0m in \u001b[0;36m\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": [ - "

** Question 4**

\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": [ - "

** Question 5**

\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": [ - "

** Question 6**

\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": [ - "

** Question 7**

\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\u001b[0m in \u001b[0;36m\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", - "## Student Answer\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": [ - "

** Question 8**

\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": [ - "

** Question 9**

\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": [ - "

** Question 10**

\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": [ - "

** Question 11**

\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", - "![UCSC Home Page](https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/images/lab4/select_NKcells.png)\n", - " \n", - "3. Search for the gene 'Gzma' and click 'View data on UCSC Genome Browser'\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---\n", - "## Student Answer\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": [ - "

** Question 12**

\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": [ - "

** Question 13**

\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": [ - "

** Bonus Question**

\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 -} +{ + "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": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
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
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
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
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
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
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
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
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
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
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
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)Normal T Cells \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", + "

Dysfunctional T Cells

\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": [ + "

** Question 1**

\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", + "## Student Answer\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": [ + "

** Question 2**

\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": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chr start end peak_annotation symbol score
chr1 9772732 9773228 intergenic 1700034P13Rik 10.0271
chr1 9797805 9798616 promoter Sgk3 8.74773
chr1 9859046 9859750 intron Sgk3 -22.0576
chr1 10089499 10089955 intron Cspp1 5.03553
chr1 20933432 20933875 intron Paqr8 9.99897
chr1 23255935 23256632 intergenic Mir30a 9.06698
chr1 34867183 34867587 intron Plekhb2 23.9799
chr1 35890111 35890946 intergenic Hs6st1 8.13463
chr1 39478274 39479009 promoter Tbc1d8 18.8915
chr1 40514972 40515601 promoter Il18rap -16.9661
\n", + "

... (26291 rows omitted)** Question 3** \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\u001b[0m in \u001b[0;36m\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": [ + "

** Question 4**

\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": [ + "

** Question 5**

\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": [ + "

** Question 6**

\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": [ + "

** Question 7**

\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\u001b[0m in \u001b[0;36m\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", + "## Student Answer\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": [ + "

** Question 8**

\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": [ + "

** Question 9**

\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": [ + "

** Question 10**

\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": [ + "

** Question 11**

\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", + "![UCSC Home Page](https://raw.githubusercontent.com/data-8/mcb-88-connector/gh-pages/images/lab4/select_NKcells.png)\n", + " \n", + "3. Search for the gene 'Gzma' and click 'View data on UCSC Genome Browser'\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Student Answer\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": [ + "

** Question 12**

\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": [ + "

** Question 13**

\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": [ + "

** Bonus Question**

\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 +}