├── CODE_OF_CONDUCT.md ├── Contributing.md ├── README.md ├── notebooks ├── Jupyter.ipynb ├── Spark.ipynb ├── Telemetry Hello World.ipynb └── pandas.ipynb └── slides ├── Telemetry Onboarding 2.0.key ├── Telemetry Onboarding 2.0.pdf ├── Telemetry Onboarding.pdf └── Telemetry Onboarding.pptx /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Participation Guidelines 2 | 3 | This repository is governed by Mozilla's code of conduct and etiquette guidelines. 4 | For more details, please read the 5 | [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). 6 | 7 | ## How to Report 8 | For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page. 9 | 10 | 16 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Firefox Data Platform projects 2 | 3 | This is a tutorial on how to work with the various Firefox Data Platform projects. 4 | 5 | ## Github Workflow @ Fx Data Platform 6 | 7 | The Firefox Data Platform team makes extensive use of Git, and particularly Github for many projects. This document describes the ideal approach to working with repositories on Github. 8 | 9 | ### Creating a new repo 10 | 11 | Feel free to create the repo under your own account for initial development or skunkworks projects. 12 | 13 | Once a project approaches “production quality”, it should be moved to one of the official Mozilla github organizations: either “mozilla” or “mozilla-services”. This move can be requested in #github on IRC, and when you request the move, you should also request that the “telemetry” group own the repo after it has been moved. If you find you’re not in the “telemetry” group, you should request to be added. 14 | 15 | ### Branches and PRs 16 | 17 | Create a new branch to work on a new feature. Try to keep the work focused on a single logical change or feature. Ideally there should be a bug filed in bugzilla for the task. 18 | 19 | To submit changes, make a personal fork of the repository, push your branch there, and open a pull request. 20 | Keeping development branches on forks keeps the upstream repository cleaner and lessens the chance of accidentally 21 | pushing changes to master prematurely. 22 | Pushing branches upstream should be reserved for cases where your changes need to be tested or built 23 | by the CI pipeline. 24 | 25 | #### Atomic commits 26 | 27 | Each commit should make a single standalone change if possible, so that the resulting branch contains a series of logical steps to make the full change or implement the feature. The list of commits in a patch should tell the story of how the patch evolved but every single commit should ideally pass a test suite run. 28 | 29 | ##### Why should we care about atomic commits? 30 | 31 | To follow the `atomic commits` workflow requires a time investment from the patch author, but that time will be vastly regained in the review process. The idea is that a reviewer’s time is very valuable, even only because there are usually more contributors than reviewers. Once the patch author gets used to the atomic commit workflow, not much effort will be required to organise the commits and that will result in a win-win. 32 | 33 | Another good point in favor of the atomic commits workflow is that it works well for history archeology. Cherry-picking and bisection are almost useless when you have either meaningless or giant commits. 34 | 35 | ##### Organizing your commits 36 | 37 | In order to properly organise your work, there are several git subcommand that may be of help: 38 | 39 | `git commit --amend` modifies the last commit in the current branch (including the commit message) 40 | 41 | `git rebase -i ^` interactively change your past commits. This is one of the best ways to rearrange your commits. It lets you reorder, delete, amend, combine, and reword your commit history. 42 | 43 | `git commit --fixup ` create a new ‘fixup’ commit for a previous commit. The new commit can be then rebased 44 | 45 | Bonus points if you use `git commit --fixup` in combination with `git rebase -i ^ --autosquash` to automatically rearrange your fixup commits in the right place. 46 | 47 | ##### When to squash commits 48 | 49 | In practice, the process of code review (more on that in the next major section below) 50 | may lead you to push several small fixup commits to respond to reviewer comments. 51 | If these make sense as atomic commits, then by all means 52 | the pull request can be merged via the default "Rebase and merge" process that preserves each commit. 53 | If, however, the overall scope of the pull request is small and a single commit seems like a 54 | better logical chunk to include in the repository's history, you may want to squash your 55 | changes to a single commit before merging. You can either do the squashing yourself and 56 | push to the branch before merging into master or you may use GitHub's 57 | "Squash and merge" functionality to handle the rebase if that option is enabled for the repository. 58 | 59 | #### Commit message 60 | 61 | There are several guides online that talk about this topic. The tl;dr is to keep it informative and succinct. First line no more than 50 chars long and eventually a blank line and an extended description. 62 | 63 | On many projects there are conventions in use, like prefixing the message with the issue/bug number or use an imperative form for verbs. The best thing to do here is to check the project history and follow the same conventions. For new projects you can ask your mentor/peers on what’s best to do. 64 | 65 | Here is an article on [How to Write a good Git Commit Message](http://chris.beams.io/posts/git-commit/). 66 | 67 | ### Reviews 68 | 69 | Code should not be merged into an official mozilla github project without being reviewed by one of your peers. If you don’t know who to ask for review, check the history of the project or files. If it is a brand new repository, ask someone on your team. 70 | 71 | Typically the person reviewing the change will merge the branch once all feedback has been addressed. If they do not have permission to merge, they will comment with "r+" or similar (a convention borrowed from [Bugzilla flags](https://bmo.readthedocs.io/en/latest/using/editing.html#flags)), at which point the author can merge the change. 72 | 73 | As either a submitter or reviewer, make an effort to be explicit about where you stand in the review process and make sure the PR's `Reviewers` field reflects that. If the reviewer requested changes and you've addressed them, select that person again in `Reviewers` in order to explicitly flag them for another round of review. If you're reviewing for another person with commit access and have only minor comments that shouldn't prevent merging, mark your review as an approval and comment with "r+ with changes" or the like to make it clear no further review is required and the submitter can merge as they're ready. 74 | 75 | For any complex review, or really any review at all, the reviewable.io tool is invaluable. Please try to use this if possible. Major advantages include the ability to keep track of changes even if the commits are rebased or modified, tracking of whether individual comments have been addressed or not, and batching up of feedback (so the conversation generates a single notification per iteration instead of a notification per comment). 76 | 77 | #### Code review checklist 78 | 79 | TODO 80 | 81 | ### New webdev projects 82 | 83 | #### Django (with Sugardough) 84 | 85 | If you need to start a new project that involves web development a good starting point is [Sugardough](https://github.com/mozilla/sugardough), a [Django](https://www.djangoproject.com/) project template made by some [awesome people](https://github.com/mozilla/sugardough/graphs/contributors) in the Mozilla webdev community. It comes with lots of goodies and sane defaults: readthedocs, travis, converalls, docker-compose, etc. See [the project readme](https://github.com/mozilla/sugardough#sugardough) for a more extensive list of features. 86 | 87 | #### Django Rest Framework 88 | 89 | If your project requires a restful api, please do yourself a favor and consider using [Django Rest Framework](http://www.django-rest-framework.org/). It integrates well with the Django ORM, although it's not a requirement, and the Django authentication system. It's fully configurable and it comes with standard-compliant defaults. 90 | It also provides a documentation site for your api where users can test it directly. 91 | 92 | Both Django and Django Rest Framework have been used by the Mozilla webdev community for years and their value has been even recognised with a [MOSS grant](https://wiki.mozilla.org/MOSS) 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository is obsolete! Please see the [Firefox Data Documentation](https://docs.telemetry.mozilla.org/) instead. 2 | -------------------------------------------------------------------------------- /notebooks/Jupyter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Jupyter tutorial" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Jupyter is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, that offers introspection, rich media, shell syntax, tab completion, and history." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "You don’t need to know anything beyond Python to start using IPython – just type commands as you would at the standard Python prompt. TAB completion works in many contexts!" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 1, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "data": { 33 | "text/plain": [ 34 | "6" 35 | ] 36 | }, 37 | "execution_count": 1, 38 | "metadata": {}, 39 | "output_type": "execute_result" 40 | } 41 | ], 42 | "source": [ 43 | "3 + 3" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [ 53 | { 54 | "data": { 55 | "text/plain": [ 56 | "55" 57 | ] 58 | }, 59 | "execution_count": 2, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "def fib(n):\n", 66 | " if n==1 or n==2: return 1\n", 67 | " else: return fib(n-1) + fib(n-2)\n", 68 | " \n", 69 | "fib(10)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "##### Getting help" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 3, 82 | "metadata": { 83 | "collapsed": true 84 | }, 85 | "outputs": [], 86 | "source": [ 87 | "%quickref" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "Typing object_name? will print all sorts of details about any object, including docstrings, function definition lines (for call arguments) and constructor details for classes. " 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 4, 100 | "metadata": { 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "dir?" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 5, 111 | "metadata": { 112 | "collapsed": false 113 | }, 114 | "outputs": [ 115 | { 116 | "name": "stdout", 117 | "output_type": "stream", 118 | "text": [ 119 | "Help on built-in function dir in module __builtin__:\n", 120 | "\n", 121 | "dir(...)\n", 122 | " dir([object]) -> list of strings\n", 123 | " \n", 124 | " If called without an argument, return the names in the current scope.\n", 125 | " Else, return an alphabetized list of names comprising (some of) the attributes\n", 126 | " of the given object, and of attributes reachable from it.\n", 127 | " If the object supplies a method named __dir__, it will be used; otherwise\n", 128 | " the default dir() logic is used and returns:\n", 129 | " for a module object: the module's attributes.\n", 130 | " for a class object: its attributes, and recursively the attributes\n", 131 | " of its bases.\n", 132 | " for any other object: its attributes, its class's attributes, and\n", 133 | " recursively the attributes of its class's base classes.\n", 134 | "\n" 135 | ] 136 | } 137 | ], 138 | "source": [ 139 | "help(dir)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "##### Magic functions" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "IPython has a set of predefined ‘magic functions’ that you can call with a command line style syntax. There are two kinds of magics, line-oriented and cell-oriented. Line magics are prefixed with the % character and work much like OS command-line calls: they get as an argument the rest of the line, where arguments are passed without parentheses or quotes. Cell magics are prefixed with a double %%, and they are functions that get as an argument not only the rest of the line, but also the lines below it in a separate argument." 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "The magic commands %pdoc, %pdef, %psource and %pfile will respectively print the docstring, function definition line, full source code and the complete file for any object (when they can be found). If automagic is on (it is by default), you don’t need to type the ‘%’ explicitly. See this section for more." 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 6, 166 | "metadata": { 167 | "collapsed": false 168 | }, 169 | "outputs": [ 170 | { 171 | "name": "stdout", 172 | "output_type": "stream", 173 | "text": [ 174 | " \u001b[0mfib\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 175 | " " 176 | ] 177 | } 178 | ], 179 | "source": [ 180 | "%pdef fib" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 7, 186 | "metadata": { 187 | "collapsed": false 188 | }, 189 | "outputs": [], 190 | "source": [ 191 | "%psource fib" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": {}, 197 | "source": [ 198 | "To time the execution of a python statement or expression:" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 8, 204 | "metadata": { 205 | "collapsed": false 206 | }, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "10000000 loops, best of 3: 22.9 ns per loop\n" 213 | ] 214 | } 215 | ], 216 | "source": [ 217 | "%timeit x = 10" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 9, 223 | "metadata": { 224 | "collapsed": false 225 | }, 226 | "outputs": [ 227 | { 228 | "name": "stdout", 229 | "output_type": "stream", 230 | "text": [ 231 | "CPU times: user 0 ns, sys: 0 ns, total: 0 ns\n", 232 | "Wall time: 10 µs\n" 233 | ] 234 | } 235 | ], 236 | "source": [ 237 | "%time x = 10" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "To run a statement through the python profiler:" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 10, 250 | "metadata": { 251 | "collapsed": false 252 | }, 253 | "outputs": [ 254 | { 255 | "name": "stdout", 256 | "output_type": "stream", 257 | "text": [ 258 | " " 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "%prun x = 10" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "To enable debugging:" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 11, 276 | "metadata": { 277 | "collapsed": false 278 | }, 279 | "outputs": [ 280 | { 281 | "name": "stdout", 282 | "output_type": "stream", 283 | "text": [ 284 | "Automatic pdb calling has been turned ON\n" 285 | ] 286 | } 287 | ], 288 | "source": [ 289 | "%pdb" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "Use the Python debugger, pdb. The %pdb command allows you to toggle on and off the automatic invocation of an IPython-enhanced pdb debugger (with coloring, tab completion and more) at any uncaught exception. The advantage of this is that pdb starts inside the function where the exception occurred, with all data still available. You can print variables, see code, execute statements and even walk up and down the call stack to track down the true source of the problem (which often is many layers in the stack above where the exception gets triggered" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 12, 302 | "metadata": { 303 | "collapsed": false 304 | }, 305 | "outputs": [ 306 | { 307 | "ename": "Exception", 308 | "evalue": "", 309 | "output_type": "error", 310 | "traceback": [ 311 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 312 | "\u001b[1;31mException\u001b[0m Traceback (most recent call last)", 313 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mprint\u001b[0m \u001b[0mfoo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 314 | "\u001b[1;32m\u001b[0m in \u001b[0;36mfoo\u001b[1;34m(n)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mfoo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mprint\u001b[0m \u001b[0mfoo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 315 | "\u001b[1;31mException\u001b[0m: " 316 | ] 317 | }, 318 | { 319 | "name": "stdout", 320 | "output_type": "stream", 321 | "text": [ 322 | "> \u001b[1;32m\u001b[0m(2)\u001b[0;36mfoo\u001b[1;34m()\u001b[0m\n", 323 | "\u001b[1;32m 1 \u001b[1;33m\u001b[1;32mdef\u001b[0m \u001b[0mfoo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 324 | "\u001b[0m\u001b[1;32m----> 2 \u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 325 | "\u001b[0m\u001b[1;32m 3 \u001b[1;33m\u001b[1;33m\u001b[0m\u001b[0m\n", 326 | "\u001b[0m\n", 327 | "\n", 328 | "KeyboardInterrupt\n" 329 | ] 330 | } 331 | ], 332 | "source": [ 333 | "def foo(n):\n", 334 | " raise Exception\n", 335 | "\n", 336 | "print foo(5)" 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": {}, 342 | "source": [ 343 | "###### System commands" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": 13, 349 | "metadata": { 350 | "collapsed": false 351 | }, 352 | "outputs": [], 353 | "source": [ 354 | "!echo \"foobar\" > /tmp/foo" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": 14, 360 | "metadata": { 361 | "collapsed": false 362 | }, 363 | "outputs": [ 364 | { 365 | "name": "stdout", 366 | "output_type": "stream", 367 | "text": [ 368 | "foobar\r\n" 369 | ] 370 | } 371 | ], 372 | "source": [ 373 | "!cat /tmp/foo" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 15, 379 | "metadata": { 380 | "collapsed": true 381 | }, 382 | "outputs": [], 383 | "source": [ 384 | "out = !ls /" 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": 16, 390 | "metadata": { 391 | "collapsed": false 392 | }, 393 | "outputs": [ 394 | { 395 | "name": "stdout", 396 | "output_type": "stream", 397 | "text": [ 398 | "['backports', 'bin', 'boot', 'dev', 'etc', 'home', 'include', 'lib', 'lib64', 'local', 'lost+found', 'media', 'mnt', 'mnt1', 'opt', 'proc', 'root', 'sbin', 'selinux', 'share', 'srv', 'sys', 'tmp', 'usr', 'var']\n" 399 | ] 400 | } 401 | ], 402 | "source": [ 403 | "print out" 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": {}, 409 | "source": [ 410 | "#### Exercises" 411 | ] 412 | }, 413 | { 414 | "cell_type": "markdown", 415 | "metadata": {}, 416 | "source": [ 417 | "1. Take the User Interface Tour (Help menu)" 418 | ] 419 | } 420 | ], 421 | "metadata": { 422 | "kernelspec": { 423 | "display_name": "Python 2", 424 | "language": "python", 425 | "name": "python2" 426 | }, 427 | "language_info": { 428 | "codemirror_mode": { 429 | "name": "ipython", 430 | "version": 2 431 | }, 432 | "file_extension": ".py", 433 | "mimetype": "text/x-python", 434 | "name": "python", 435 | "nbconvert_exporter": "python", 436 | "pygments_lexer": "ipython2", 437 | "version": "2.7.11" 438 | } 439 | }, 440 | "nbformat": 4, 441 | "nbformat_minor": 0 442 | } 443 | -------------------------------------------------------------------------------- /notebooks/Spark.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### RDD" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Let's create our first [RDD](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.rdd.RDD). A Resilient Distributed Dataset (RDD), the basic abstraction in Spark. Represents an immutable, partitioned collection of elements that can be operated on in parallel. Spark applications run as independent sets of processes on a cluster, coordinated by the SparkContext object in your main program (called the driver)." 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": { 21 | "collapsed": true 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "dataset = sc.parallelize(range(1000))" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "A RDD is divided in partitions." 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": { 39 | "collapsed": false 40 | }, 41 | "outputs": [ 42 | { 43 | "data": { 44 | "text/plain": [ 45 | "'(16) ParallelCollectionRDD[0] at parallelize at PythonRDD.scala:392 []'" 46 | ] 47 | }, 48 | "execution_count": 2, 49 | "metadata": {}, 50 | "output_type": "execute_result" 51 | } 52 | ], 53 | "source": [ 54 | "dataset.toDebugString()" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "[RDD](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.rdd.RDD) support two type of operations: transformations and actions. " 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "### RDD Transformations" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "A transformation creates a new dataset from an existing one." 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 3, 81 | "metadata": { 82 | "collapsed": true 83 | }, 84 | "outputs": [], 85 | "source": [ 86 | "squared = dataset.map(lambda x: x*x)" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "The map operation is a method of the RDD, while the lambda function passed as argument is a common Python function. As long the code is serializable there are no restrictions on the kind of Python code that can be executed. Note that all transformations in Spark are lazy; an action is required to actually realize a transformation, which explains why the map returned so quickly." 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "Let's keep all multiples of 3." 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 4, 106 | "metadata": { 107 | "collapsed": false 108 | }, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "PythonRDD[1] at RDD at PythonRDD.scala:43" 114 | ] 115 | }, 116 | "execution_count": 4, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "dataset.filter(lambda x: x % 3 == 0)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "Let's get a 10% sample without replacement." 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 5, 135 | "metadata": { 136 | "collapsed": false 137 | }, 138 | "outputs": [ 139 | { 140 | "data": { 141 | "text/plain": [ 142 | "PythonRDD[2] at RDD at PythonRDD.scala:43" 143 | ] 144 | }, 145 | "execution_count": 5, 146 | "metadata": {}, 147 | "output_type": "execute_result" 148 | } 149 | ], 150 | "source": [ 151 | "dataset.sample(False, 0.1)" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "### RDD Actions" 159 | ] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "metadata": {}, 164 | "source": [ 165 | "An action returns a value after running a computation on the dataset." 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 6, 171 | "metadata": { 172 | "collapsed": false 173 | }, 174 | "outputs": [ 175 | { 176 | "data": { 177 | "text/plain": [ 178 | "1000" 179 | ] 180 | }, 181 | "execution_count": 6, 182 | "metadata": {}, 183 | "output_type": "execute_result" 184 | } 185 | ], 186 | "source": [ 187 | "squared.count()" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "Get the first element." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 7, 200 | "metadata": { 201 | "collapsed": false 202 | }, 203 | "outputs": [ 204 | { 205 | "data": { 206 | "text/plain": [ 207 | "0" 208 | ] 209 | }, 210 | "execution_count": 7, 211 | "metadata": {}, 212 | "output_type": "execute_result" 213 | } 214 | ], 215 | "source": [ 216 | "squared.first()" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "Get the first k elements." 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 8, 229 | "metadata": { 230 | "collapsed": false 231 | }, 232 | "outputs": [ 233 | { 234 | "data": { 235 | "text/plain": [ 236 | "[0, 1, 4, 9, 16]" 237 | ] 238 | }, 239 | "execution_count": 8, 240 | "metadata": {}, 241 | "output_type": "execute_result" 242 | } 243 | ], 244 | "source": [ 245 | "squared.take(5)" 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "metadata": {}, 251 | "source": [ 252 | "Get a Python list of all elements." 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 9, 258 | "metadata": { 259 | "collapsed": false 260 | }, 261 | "outputs": [ 262 | { 263 | "data": { 264 | "text/plain": [ 265 | "[0, 1, 4, 9, 16]" 266 | ] 267 | }, 268 | "execution_count": 9, 269 | "metadata": {}, 270 | "output_type": "execute_result" 271 | } 272 | ], 273 | "source": [ 274 | "squared.collect()[:5]" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "Note that you can't access an arbitrary row of the RDD." 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "Reduce the elements of the RDD." 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": 10, 294 | "metadata": { 295 | "collapsed": false 296 | }, 297 | "outputs": [ 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "332833500" 302 | ] 303 | }, 304 | "execution_count": 10, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "squared.reduce(lambda x, y: x + y)" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "metadata": {}, 316 | "source": [ 317 | "### RDD Caching" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "metadata": {}, 323 | "source": [ 324 | "Rerunning an action will retrigger the computation." 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": 11, 330 | "metadata": { 331 | "collapsed": false 332 | }, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "1000" 338 | ] 339 | }, 340 | "execution_count": 11, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | } 344 | ], 345 | "source": [ 346 | "squared.count()" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "We can cache a RDD so that successive accesses to it don't recompute the whole thing." 354 | ] 355 | }, 356 | { 357 | "cell_type": "code", 358 | "execution_count": 12, 359 | "metadata": { 360 | "collapsed": false 361 | }, 362 | "outputs": [ 363 | { 364 | "data": { 365 | "text/plain": [ 366 | "PythonRDD[4] at RDD at PythonRDD.scala:43" 367 | ] 368 | }, 369 | "execution_count": 12, 370 | "metadata": {}, 371 | "output_type": "execute_result" 372 | } 373 | ], 374 | "source": [ 375 | "squared.cache()" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": 13, 381 | "metadata": { 382 | "collapsed": false 383 | }, 384 | "outputs": [ 385 | { 386 | "data": { 387 | "text/plain": [ 388 | "1000" 389 | ] 390 | }, 391 | "execution_count": 13, 392 | "metadata": {}, 393 | "output_type": "execute_result" 394 | } 395 | ], 396 | "source": [ 397 | "squared.count()" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 14, 403 | "metadata": { 404 | "collapsed": false 405 | }, 406 | "outputs": [ 407 | { 408 | "data": { 409 | "text/plain": [ 410 | "1000" 411 | ] 412 | }, 413 | "execution_count": 14, 414 | "metadata": {}, 415 | "output_type": "execute_result" 416 | } 417 | ], 418 | "source": [ 419 | "squared.count()" 420 | ] 421 | }, 422 | { 423 | "cell_type": "markdown", 424 | "metadata": {}, 425 | "source": [ 426 | "Once we are done with a dataset we can remove it from memory." 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "execution_count": 15, 432 | "metadata": { 433 | "collapsed": false 434 | }, 435 | "outputs": [ 436 | { 437 | "data": { 438 | "text/plain": [ 439 | "PythonRDD[4] at RDD at PythonRDD.scala:43" 440 | ] 441 | }, 442 | "execution_count": 15, 443 | "metadata": {}, 444 | "output_type": "execute_result" 445 | } 446 | ], 447 | "source": [ 448 | "squared.unpersist()" 449 | ] 450 | }, 451 | { 452 | "cell_type": "markdown", 453 | "metadata": {}, 454 | "source": [ 455 | "Doesn't seem like much right now but once you start handling some real datasets you will appreciate the speed boost, assuming it fits in memory that is. Check out this [documentation](http://spark.apache.org/docs/latest/programming-guide.html#rdd-persistence) to learn more about the persistence policies." 456 | ] 457 | }, 458 | { 459 | "cell_type": "markdown", 460 | "metadata": {}, 461 | "source": [ 462 | "### Key-value pairs" 463 | ] 464 | }, 465 | { 466 | "cell_type": "markdown", 467 | "metadata": {}, 468 | "source": [ 469 | "Most Spark operations work on RDDs of any types but few are reserved for key-value pairs, the most common ones are distributed “shuffle” operations, such as grouping or aggregating the elements by a key." 470 | ] 471 | }, 472 | { 473 | "cell_type": "code", 474 | "execution_count": 16, 475 | "metadata": { 476 | "collapsed": true 477 | }, 478 | "outputs": [], 479 | "source": [ 480 | "grouped = dataset.map(lambda x: (x % 2 == 0, x))" 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": {}, 486 | "source": [ 487 | "We can reduce by key," 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 17, 493 | "metadata": { 494 | "collapsed": false 495 | }, 496 | "outputs": [ 497 | { 498 | "data": { 499 | "text/plain": [ 500 | "{False: 250000, True: 249500}" 501 | ] 502 | }, 503 | "execution_count": 17, 504 | "metadata": {}, 505 | "output_type": "execute_result" 506 | } 507 | ], 508 | "source": [ 509 | "grouped.reduceByKey(lambda x, y: x + y).collectAsMap()" 510 | ] 511 | }, 512 | { 513 | "cell_type": "markdown", 514 | "metadata": {}, 515 | "source": [ 516 | "... group by key," 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": 18, 522 | "metadata": { 523 | "collapsed": false 524 | }, 525 | "outputs": [ 526 | { 527 | "data": { 528 | "text/plain": [ 529 | "{False: ,\n", 530 | " True: }" 531 | ] 532 | }, 533 | "execution_count": 18, 534 | "metadata": {}, 535 | "output_type": "execute_result" 536 | } 537 | ], 538 | "source": [ 539 | "grouped.groupByKey().collectAsMap()" 540 | ] 541 | }, 542 | { 543 | "cell_type": "markdown", 544 | "metadata": {}, 545 | "source": [ 546 | "or count by key (action)." 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 19, 552 | "metadata": { 553 | "collapsed": false 554 | }, 555 | "outputs": [ 556 | { 557 | "data": { 558 | "text/plain": [ 559 | "defaultdict(, {False: 500, True: 500})" 560 | ] 561 | }, 562 | "execution_count": 19, 563 | "metadata": {}, 564 | "output_type": "execute_result" 565 | } 566 | ], 567 | "source": [ 568 | "grouped.countByKey()" 569 | ] 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": {}, 574 | "source": [ 575 | "Check out the [documentation](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.rdd.PairRDDFunctions) for a complete list of operations on key-value pairs." 576 | ] 577 | }, 578 | { 579 | "cell_type": "markdown", 580 | "metadata": {}, 581 | "source": [ 582 | "### Scalars" 583 | ] 584 | }, 585 | { 586 | "cell_type": "markdown", 587 | "metadata": {}, 588 | "source": [ 589 | "Some simple stats operations are reserved for RDDs of scalars." 590 | ] 591 | }, 592 | { 593 | "cell_type": "code", 594 | "execution_count": 20, 595 | "metadata": { 596 | "collapsed": false 597 | }, 598 | "outputs": [ 599 | { 600 | "data": { 601 | "text/plain": [ 602 | "499.5" 603 | ] 604 | }, 605 | "execution_count": 20, 606 | "metadata": {}, 607 | "output_type": "execute_result" 608 | } 609 | ], 610 | "source": [ 611 | "dataset.mean()" 612 | ] 613 | }, 614 | { 615 | "cell_type": "code", 616 | "execution_count": 21, 617 | "metadata": { 618 | "collapsed": false 619 | }, 620 | "outputs": [ 621 | { 622 | "data": { 623 | "text/plain": [ 624 | "499500" 625 | ] 626 | }, 627 | "execution_count": 21, 628 | "metadata": {}, 629 | "output_type": "execute_result" 630 | } 631 | ], 632 | "source": [ 633 | "dataset.sum()" 634 | ] 635 | }, 636 | { 637 | "cell_type": "code", 638 | "execution_count": 22, 639 | "metadata": { 640 | "collapsed": false 641 | }, 642 | "outputs": [ 643 | { 644 | "data": { 645 | "text/plain": [ 646 | "288.67499025720952" 647 | ] 648 | }, 649 | "execution_count": 22, 650 | "metadata": {}, 651 | "output_type": "execute_result" 652 | } 653 | ], 654 | "source": [ 655 | "dataset.stdev()" 656 | ] 657 | }, 658 | { 659 | "cell_type": "markdown", 660 | "metadata": {}, 661 | "source": [ 662 | "You can also create a simple textual histogram." 663 | ] 664 | }, 665 | { 666 | "cell_type": "code", 667 | "execution_count": 23, 668 | "metadata": { 669 | "collapsed": false 670 | }, 671 | "outputs": [ 672 | { 673 | "data": { 674 | "text/plain": [ 675 | "([0.0,\n", 676 | " 99.9,\n", 677 | " 199.8,\n", 678 | " 299.70000000000005,\n", 679 | " 399.6,\n", 680 | " 499.5,\n", 681 | " 599.4000000000001,\n", 682 | " 699.3000000000001,\n", 683 | " 799.2,\n", 684 | " 899.1,\n", 685 | " 999],\n", 686 | " [100, 100, 100, 100, 100, 100, 100, 100, 100, 100])" 687 | ] 688 | }, 689 | "execution_count": 23, 690 | "metadata": {}, 691 | "output_type": "execute_result" 692 | } 693 | ], 694 | "source": [ 695 | "dataset.histogram(10)" 696 | ] 697 | }, 698 | { 699 | "cell_type": "markdown", 700 | "metadata": {}, 701 | "source": [ 702 | "Check out the [documentation](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.rdd.DoubleRDDFunctions) for a complete list of operations on doubles." 703 | ] 704 | }, 705 | { 706 | "cell_type": "markdown", 707 | "metadata": {}, 708 | "source": [ 709 | "##### Exercises" 710 | ] 711 | }, 712 | { 713 | "cell_type": "markdown", 714 | "metadata": { 715 | "collapsed": true 716 | }, 717 | "source": [ 718 | "1) Write some code that prints the numbers from 1 to 1000. But for multiples of three print \"Fizz\" instead of the number and for the multiples of five print \"Buzz\". For numbers which are multiples of both three and five print \"FizzBuzz\"." 719 | ] 720 | } 721 | ], 722 | "metadata": { 723 | "kernelspec": { 724 | "display_name": "Python 2", 725 | "language": "python", 726 | "name": "python2" 727 | }, 728 | "language_info": { 729 | "codemirror_mode": { 730 | "name": "ipython", 731 | "version": 2 732 | }, 733 | "file_extension": ".py", 734 | "mimetype": "text/x-python", 735 | "name": "python", 736 | "nbconvert_exporter": "python", 737 | "pygments_lexer": "ipython2", 738 | "version": "2.7.9" 739 | } 740 | }, 741 | "nbformat": 4, 742 | "nbformat_minor": 0 743 | } 744 | -------------------------------------------------------------------------------- /notebooks/Telemetry Hello World.ipynb: -------------------------------------------------------------------------------- 1 | {"nbformat_minor": 0, "cells": [{"source": "### Telemetry Hello World", "cell_type": "markdown", "metadata": {}}, {"source": "This is a very a brief introduction to Spark and Telemetry in Python. You should have a look at the [tutorial](https://gist.github.com/vitillo/25a20b7c8685c0c82422) in Scala and the associated [talk](http://www.slideshare.net/RobertoAgostinoVitil/spark-meets-telemetry) if you are interested to learn more about Spark.", "cell_type": "markdown", "metadata": {}}, {"execution_count": 1, "cell_type": "code", "source": "import ujson as json\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\nimport plotly.plotly as py\n\nfrom moztelemetry import get_pings, get_pings_properties, get_one_ping_per_client\n\n%pylab inline", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Populating the interactive namespace from numpy and matplotlib\n"}], "metadata": {"scrolled": true, "collapsed": false, "trusted": false}}, {"source": "### Basics", "cell_type": "markdown", "metadata": {}}, {"source": "The goal of this example is to plot the startup distribution for each OS. Let's see how many parallel workers we have at our disposal:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 2, "cell_type": "code", "source": "sc.defaultParallelism", "outputs": [{"execution_count": 2, "output_type": "execute_result", "data": {"text/plain": "16"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": false}}, {"source": "Let's fetch 10% of Telemetry submissions for a given build-id...", "cell_type": "markdown", "metadata": {}}, {"execution_count": 4, "cell_type": "code", "source": "pings = get_pings(sc, app=\"Firefox\", channel=\"nightly\", build_id=(\"20150520000000\", \"20150520999999\"), fraction=0.1)", "outputs": [], "metadata": {"collapsed": false, "trusted": false}}, {"source": "... and extract only the attributes we need from the Telemetry submissions:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 5, "cell_type": "code", "source": "subset = get_pings_properties(pings, [\"clientId\",\n \"environment/system/os/name\",\n \"payload/simpleMeasurements/firstPaint\"])", "outputs": [], "metadata": {"collapsed": false, "trusted": false}}, {"source": "Let's filter out submissions with an invalid startup time:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 6, "cell_type": "code", "source": "subset = subset.filter(lambda p: p.get(\"payload/simpleMeasurements/firstPaint\", -1) >= 0)", "outputs": [], "metadata": {"collapsed": false, "trusted": false}}, {"source": "To prevent pseudoreplication, let's consider only a single submission for each client. As this step requires a distributed shuffle, it should always be run only after extracting the attributes of interest with *get_pings_properties*.", "cell_type": "markdown", "metadata": {}}, {"execution_count": 7, "cell_type": "code", "source": "subset = get_one_ping_per_client(subset)", "outputs": [], "metadata": {"collapsed": false, "trusted": false}}, {"source": "How many pings are we looking at?", "cell_type": "markdown", "metadata": {}}, {"execution_count": 8, "cell_type": "code", "source": "subset.count()", "outputs": [{"execution_count": 8, "output_type": "execute_result", "data": {"text/plain": "1195"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": false}}, {"source": "Let's group the startup timings by OS:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 9, "cell_type": "code", "source": "grouped = subset.map(lambda p: (p[\"environment/system/os/name\"], p[\"payload/simpleMeasurements/firstPaint\"])).groupByKey().collectAsMap()", "outputs": [], "metadata": {"collapsed": false, "trusted": false}}, {"source": "And finally plot the data:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 10, "cell_type": "code", "source": "frame = pd.DataFrame({x: np.log10(pd.Series(list(y))) for x, y in grouped.items()})\nplt.figure(figsize=(17, 7))\nframe.boxplot(return_type=\"axes\")\nplt.ylabel(\"log10(firstPaint)\")\nplt.show()", "outputs": [{"output_type": "display_data", "data": {"image/png": "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\ny4JnAe2EHOEAAAAASUVORK5CYII=\n", "text/plain": ""}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": false}}, {"source": "###Histograms", "cell_type": "markdown", "metadata": {}}, {"source": "Let's fetch some pings first:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 12, "cell_type": "code", "source": "pings = get_pings(sc, app=\"Firefox\", channel=\"nightly\", submission_date=\"20150426\", fraction=0.1)", "outputs": [], "metadata": {"collapsed": true, "trusted": false}}, {"source": "Let's extract a histogram from the submissions:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 13, "cell_type": "code", "source": "histograms = get_pings_properties(pings, \"payload/histograms/GC_MARK_MS\", with_processes=True)", "outputs": [], "metadata": {"collapsed": false, "trusted": false}}, {"source": "The API returns three distinct histograms for each submission:\n- a histogram for the parent process (*GC_MARK_MS_parent*)\n- an aggregated histogram for the child processes (*GC_MARK_MS_children*)\n- the aggregate of the parent and child histograms (*GC_MARK*)", "cell_type": "markdown", "metadata": {}}, {"source": "Let's aggregate the histogram over all submissions and plot it:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 14, "cell_type": "code", "source": "def aggregate_arrays(xs, ys):\n if xs is None:\n return ys\n \n if ys is None:\n return xs\n \n return xs + ys\n \naggregate = histograms.map(lambda p: p[\"payload/histograms/GC_MARK_MS\"]).reduce(aggregate_arrays)\naggregate.plot(kind=\"bar\", figsize=(15, 7))", "outputs": [{"execution_count": 14, "output_type": "execute_result", "data": {"text/plain": ""}, "metadata": {}}, {"output_type": "display_data", "data": {"image/png": "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\nAAAASUVORK5CYII=\n", "text/plain": ""}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": false}}, {"source": "#### Exercises", "cell_type": "markdown", "metadata": {"collapsed": true}}, {"source": "1) Plot the distribution of GC_MS faceted by OS. ", "cell_type": "markdown", "metadata": {}}, {"execution_count": null, "cell_type": "code", "source": "", "outputs": [], "metadata": {"collapsed": true, "trusted": false}}], "nbformat": 4, "metadata": {"kernelspec": {"display_name": "Python 2", "name": "python2", "language": "python"}, "language_info": {"mimetype": "text/x-python", "nbconvert_exporter": "python", "version": "2.7.9", "name": "python", "file_extension": ".py", "pygments_lexer": "ipython2", "codemirror_mode": {"version": 2, "name": "ipython"}}}} 2 | -------------------------------------------------------------------------------- /notebooks/pandas.ipynb: -------------------------------------------------------------------------------- 1 | {"nbformat_minor": 0, "cells": [{"source": "# Pandas Tutorial\n\nCredits: The following are notes taken while working through [Python for Data Analysis](http://www.amazon.com/Python-Data-Analysis-Wrangling-IPython/dp/1449319793) by Wes McKinney\n\n* Series\n* DataFrame\n* Dropping Entries\n* Indexing, Selecting, Filtering\n* Summarizing and Computing Descriptive Statistics\n* Split-apply-combine", "cell_type": "markdown", "metadata": {}}, {"execution_count": 1, "cell_type": "code", "source": "from pandas import Series, DataFrame\nimport pandas as pd\nimport numpy as np\n%pylab inline", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Populating the interactive namespace from numpy and matplotlib\n"}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "## Series\n\nA Series is a one-dimensional array-like object containing an array of data and an associated array of data labels. The data can be any NumPy data type and the labels are the Series' index.", "cell_type": "markdown", "metadata": {}}, {"source": "Create a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 2, "cell_type": "code", "source": "ser_1 = Series([1, 1, 2, -3, -5, 8, 13])\nser_1", "outputs": [{"execution_count": 2, "output_type": "execute_result", "data": {"text/plain": "0 1\n1 1\n2 2\n3 -3\n4 -5\n5 8\n6 13\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Get the array (numpy) representation of a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 3, "cell_type": "code", "source": "ser_1.values", "outputs": [{"execution_count": 3, "output_type": "execute_result", "data": {"text/plain": "array([ 1, 1, 2, -3, -5, 8, 13])"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Index objects are immutable and hold the axis labels and metadata such as names and axis names.\n\nGet the index of the Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 4, "cell_type": "code", "source": "ser_1.index", "outputs": [{"execution_count": 4, "output_type": "execute_result", "data": {"text/plain": "Int64Index([0, 1, 2, 3, 4, 5, 6], dtype='int64')"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Create a Series with a custom index:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 5, "cell_type": "code", "source": "ser_2 = Series([1, 1, 2, -3, -5], index=['a', 'b', 'c', 'd', 'e'])\nser_2", "outputs": [{"execution_count": 5, "output_type": "execute_result", "data": {"text/plain": "a 1\nb 1\nc 2\nd -3\ne -5\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Get a value from a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 6, "cell_type": "code", "source": "ser_2[4] == ser_2['e']", "outputs": [{"execution_count": 6, "output_type": "execute_result", "data": {"text/plain": "True"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Get a set of values from a Series by passing in a list:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 7, "cell_type": "code", "source": "ser_2[['c', 'a', 'b']]", "outputs": [{"execution_count": 7, "output_type": "execute_result", "data": {"text/plain": "c 2\na 1\nb 1\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Get values great than 0:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 8, "cell_type": "code", "source": "ser_2[ser_2 > 0]", "outputs": [{"execution_count": 8, "output_type": "execute_result", "data": {"text/plain": "a 1\nb 1\nc 2\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Get values between 0 and 1", "cell_type": "markdown", "metadata": {}}, {"execution_count": 9, "cell_type": "code", "source": "ser_2[(ser_2 > 0) & (ser_2 <= 1)]", "outputs": [{"execution_count": 9, "output_type": "execute_result", "data": {"text/plain": "a 1\nb 1\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Scalar multiply:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 10, "cell_type": "code", "source": "ser_2 * 2", "outputs": [{"execution_count": 10, "output_type": "execute_result", "data": {"text/plain": "a 2\nb 2\nc 4\nd -6\ne -10\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Apply a numpy math function:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 11, "cell_type": "code", "source": "np.exp(ser_2)", "outputs": [{"execution_count": 11, "output_type": "execute_result", "data": {"text/plain": "a 2.718282\nb 2.718282\nc 7.389056\nd 0.049787\ne 0.006738\ndtype: float64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "A Series is like a fixed-length, ordered dict. \n\nCreate a series by passing in a dict:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 12, "cell_type": "code", "source": "dict_1 = {'foo' : 100, 'bar' : 200, 'baz' : 300}\nser_3 = Series(dict_1)\nser_3", "outputs": [{"execution_count": 12, "output_type": "execute_result", "data": {"text/plain": "bar 200\nbaz 300\nfoo 100\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 13, "cell_type": "code", "source": "ser_4 = Series({\"bar\": 200, \"baz\": 300, \"foo\": 100, \"qux\": 50})\nser_4", "outputs": [{"execution_count": 13, "output_type": "execute_result", "data": {"text/plain": "bar 200\nbaz 300\nfoo 100\nqux 50\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Series automatically aligns differently indexed data in arithmetic operations:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 14, "cell_type": "code", "source": "ser_3 + ser_4", "outputs": [{"execution_count": 14, "output_type": "execute_result", "data": {"text/plain": "bar 400\nbaz 600\nfoo 200\nqux NaN\ndtype: float64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Name a Series:", "cell_type": "markdown", "metadata": {}}, {"source": "## DataFrame\n\nA DataFrame is a tabular data structure containing an ordered collection of columns. Each column can have a different type. DataFrames have both row and column indices and is analogous to a dict of Series. Row and column operations are treated roughly symmetrically. Columns returned when indexing a DataFrame are views of the underlying data, not a copy. To obtain a copy, use the Series' copy method.\n\nCreate a DataFrame:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 15, "cell_type": "code", "source": "data_1 = {'state' : ['VA', 'VA', 'VA', 'MD', 'MD'],\n 'year' : [2012, 2013, 2014, 2014, 2015],\n 'pop' : [5.0, 5.1, 5.2, 4.0, 4.1]}\ndf_1 = DataFrame(data_1)\ndf_1", "outputs": [{"execution_count": 15, "output_type": "execute_result", "data": {"text/plain": " pop state year\n0 5.0 VA 2012\n1 5.1 VA 2013\n2 5.2 VA 2014\n3 4.0 MD 2014\n4 4.1 MD 2015", "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
popstateyear
0 5.0 VA 2012
1 5.1 VA 2013
2 5.2 VA 2014
3 4.0 MD 2014
4 4.1 MD 2015
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Retrieve a column by key, returning a Series:\n", "cell_type": "markdown", "metadata": {}}, {"execution_count": 16, "cell_type": "code", "source": "df_1['state']", "outputs": [{"execution_count": 16, "output_type": "execute_result", "data": {"text/plain": "0 VA\n1 VA\n2 VA\n3 MD\n4 MD\nName: state, dtype: object"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Retrive a column by attribute, returning a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 17, "cell_type": "code", "source": "df_1.year", "outputs": [{"execution_count": 17, "output_type": "execute_result", "data": {"text/plain": "0 2012\n1 2013\n2 2014\n3 2014\n4 2015\nName: year, dtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Retrieve a row by position:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 18, "cell_type": "code", "source": "df_1.ix[0]", "outputs": [{"execution_count": 18, "output_type": "execute_result", "data": {"text/plain": "pop 5\nstate VA\nyear 2012\nName: 0, dtype: object"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Update a column by assignment:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 19, "cell_type": "code", "source": "df_1['unempl'] = np.arange(5)\ndf_1", "outputs": [{"execution_count": 19, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 0\n1 5.1 VA 2013 1\n2 5.2 VA 2014 2\n3 4.0 MD 2014 3\n4 4.1 MD 2015 4", "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
popstateyearunempl
0 5.0 VA 2012 0
1 5.1 VA 2013 1
2 5.2 VA 2014 2
3 4.0 MD 2014 3
4 4.1 MD 2015 4
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Assign a Series to a column (note if assigning a list or array, the length must match the DataFrame, unlike a Series):", "cell_type": "markdown", "metadata": {}}, {"execution_count": 20, "cell_type": "code", "source": "unempl = Series([6.0, 6.0, 6.1], index=[2, 3, 4])\ndf_1['unempl'] = unempl\ndf_1", "outputs": [{"execution_count": 20, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
0 5.0 VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Assign a new column that doesn't exist to create a new column:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 21, "cell_type": "code", "source": "df_1['state_dup'] = df_1['state']\ndf_1", "outputs": [{"execution_count": 21, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl state_dup\n0 5.0 VA 2012 NaN VA\n1 5.1 VA 2013 NaN VA\n2 5.2 VA 2014 6.0 VA\n3 4.0 MD 2014 6.0 MD\n4 4.1 MD 2015 6.1 MD", "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
popstateyearunemplstate_dup
0 5.0 VA 2012 NaN VA
1 5.1 VA 2013 NaN VA
2 5.2 VA 2014 6.0 VA
3 4.0 MD 2014 6.0 MD
4 4.1 MD 2015 6.1 MD
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Delete a column:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 22, "cell_type": "code", "source": "del df_1['state_dup']\ndf_1", "outputs": [{"execution_count": 22, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
0 5.0 VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "## Indexing, Selecting, Filtering", "cell_type": "markdown", "metadata": {}}, {"source": "Series indexing is similar to NumPy array indexing with the added bonus of being able to use the Series' index values.", "cell_type": "markdown", "metadata": {}}, {"execution_count": 23, "cell_type": "code", "source": "ser_2", "outputs": [{"execution_count": 23, "output_type": "execute_result", "data": {"text/plain": "a 1\nb 1\nc 2\nd -3\ne -5\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select a value from a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 24, "cell_type": "code", "source": "ser_2[0] == ser_2['a']", "outputs": [{"execution_count": 24, "output_type": "execute_result", "data": {"text/plain": "True"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select a slice from a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 25, "cell_type": "code", "source": "ser_2[1:4]", "outputs": [{"execution_count": 25, "output_type": "execute_result", "data": {"text/plain": "b 1\nc 2\nd -3\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select specific values from a Series:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 26, "cell_type": "code", "source": "ser_2[['b', 'c', 'd']]", "outputs": [{"execution_count": 26, "output_type": "execute_result", "data": {"text/plain": "b 1\nc 2\nd -3\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select from a Series based on a filter:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 27, "cell_type": "code", "source": "ser_2[ser_2 > 0]", "outputs": [{"execution_count": 27, "output_type": "execute_result", "data": {"text/plain": "a 1\nb 1\nc 2\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select a slice from a Series with labels (note the end point is inclusive):", "cell_type": "markdown", "metadata": {}}, {"execution_count": 28, "cell_type": "code", "source": "ser_2['a':'b']", "outputs": [{"execution_count": 28, "output_type": "execute_result", "data": {"text/plain": "a 1\nb 1\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Assign to a Series slice (note the end point is inclusive):", "cell_type": "markdown", "metadata": {}}, {"execution_count": 29, "cell_type": "code", "source": "ser_2['a':'b'] = 0\nser_2", "outputs": [{"execution_count": 29, "output_type": "execute_result", "data": {"text/plain": "a 0\nb 0\nc 2\nd -3\ne -5\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Pandas supports indexing into a DataFrame.", "cell_type": "markdown", "metadata": {}}, {"execution_count": 30, "cell_type": "code", "source": "df_1", "outputs": [{"execution_count": 30, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
0 5.0 VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select specified columns from a DataFrame:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 31, "cell_type": "code", "source": "df_1[['pop', 'unempl']]", "outputs": [{"execution_count": 31, "output_type": "execute_result", "data": {"text/plain": " pop unempl\n0 5.0 NaN\n1 5.1 NaN\n2 5.2 6.0\n3 4.0 6.0\n4 4.1 6.1", "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
popunempl
0 5.0 NaN
1 5.1 NaN
2 5.2 6.0
3 4.0 6.0
4 4.1 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select a slice from a DataFrame:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 32, "cell_type": "code", "source": "df_1[:2]", "outputs": [{"execution_count": 32, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN", "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
popstateyearunempl
0 5.0 VA 2012NaN
1 5.1 VA 2013NaN
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select from a DataFrame based on a filter:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 33, "cell_type": "code", "source": "df_1[df_1['pop'] > 5]", "outputs": [{"execution_count": 33, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6", "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
popstateyearunempl
1 5.1 VA 2013NaN
2 5.2 VA 2014 6
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Perform a scalar comparison on a DataFrame:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 34, "cell_type": "code", "source": "df_1 > 5", "outputs": [{"execution_count": 34, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 False True True False\n1 True True True False\n2 True True True True\n3 False True True True\n4 False True True True", "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
popstateyearunempl
0 False True True False
1 True True True False
2 True True True True
3 False True True True
4 False True True True
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Perform a scalar comparison on a DataFrame, retain the values that pass the filter:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 35, "cell_type": "code", "source": "df_1[df_1 > 5]", "outputs": [{"execution_count": 35, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 NaN VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 NaN MD 2014 6.0\n4 NaN MD 2015 6.1", "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
popstateyearunempl
0 NaN VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 NaN MD 2014 6.0
4 NaN MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select a slice of rows from a DataFrame (note the end point is inclusive):", "cell_type": "markdown", "metadata": {}}, {"execution_count": 36, "cell_type": "code", "source": "df_1.ix[2:3]", "outputs": [{"execution_count": 36, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n2 5.2 VA 2014 6\n3 4.0 MD 2014 6", "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
popstateyearunempl
2 5.2 VA 2014 6
3 4.0 MD 2014 6
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select a slice of rows from a specific column of a DataFrame:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 37, "cell_type": "code", "source": "df_1.ix[0:2, 'pop']\ndf_1", "outputs": [{"execution_count": 37, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
0 5.0 VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Select rows based on an arithmetic operation on a specific row:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 38, "cell_type": "code", "source": "df_1.ix[df_1.unempl > 5.0]", "outputs": [{"execution_count": 38, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "## Summarizing and Computing Descriptive Statistics", "cell_type": "markdown", "metadata": {}}, {"source": "Unlike NumPy arrays, Pandas descriptive statistics automatically exclude missing data. NaN values are excluded unless the entire row or column is NA.", "cell_type": "markdown", "metadata": {}}, {"execution_count": 39, "cell_type": "code", "source": "df_1", "outputs": [{"execution_count": 39, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
0 5.0 VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 40, "cell_type": "code", "source": "df_1.sum()", "outputs": [{"execution_count": 40, "output_type": "execute_result", "data": {"text/plain": "pop 23.4\nstate VAVAVAMDMD\nyear 10068\nunempl 18.1\ndtype: object"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Sum over the rows:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 41, "cell_type": "code", "source": "df_1.sum(axis=1)", "outputs": [{"execution_count": 41, "output_type": "execute_result", "data": {"text/plain": "0 2017.0\n1 2018.1\n2 2025.2\n3 2024.0\n4 2025.2\ndtype: float64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "Generate various summary statistics, excluding NaN values:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 42, "cell_type": "code", "source": "df_1.describe(include=\"all\")", "outputs": [{"execution_count": 42, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\ncount 5.000000 5 5.000000 3.000000\nunique NaN 2 NaN NaN\ntop NaN VA NaN NaN\nfreq NaN 3 NaN NaN\nmean 4.680000 NaN 2013.600000 6.033333\nstd 0.580517 NaN 1.140175 0.057735\nmin 4.000000 NaN 2012.000000 6.000000\n25% 4.100000 NaN 2013.000000 6.000000\n50% 5.000000 NaN 2014.000000 6.000000\n75% 5.100000 NaN 2014.000000 6.050000\nmax 5.200000 NaN 2015.000000 6.100000", "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
popstateyearunempl
count 5.000000 5 5.000000 3.000000
unique NaN 2 NaN NaN
top NaN VA NaN NaN
freq NaN 3 NaN NaN
mean 4.680000 NaN 2013.600000 6.033333
std 0.580517 NaN 1.140175 0.057735
min 4.000000 NaN 2012.000000 6.000000
25% 4.100000 NaN 2013.000000 6.000000
50% 5.000000 NaN 2014.000000 6.000000
75% 5.100000 NaN 2014.000000 6.050000
max 5.200000 NaN 2015.000000 6.100000
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "## Split-apply-combine", "cell_type": "markdown", "metadata": {}}, {"source": "Many data analysis problems involve the application of a split-apply-combine strategy,\nwhere you break up a big problem into manageable pieces, operate on each piece independently and then put all the pieces back together.", "cell_type": "markdown", "metadata": {}}, {"execution_count": 43, "cell_type": "code", "source": "df_1", "outputs": [{"execution_count": 43, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\n0 5.0 VA 2012 NaN\n1 5.1 VA 2013 NaN\n2 5.2 VA 2014 6.0\n3 4.0 MD 2014 6.0\n4 4.1 MD 2015 6.1", "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
popstateyearunempl
0 5.0 VA 2012 NaN
1 5.1 VA 2013 NaN
2 5.2 VA 2014 6.0
3 4.0 MD 2014 6.0
4 4.1 MD 2015 6.1
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "The groupby operation creates a new dataframe for each group:", "cell_type": "markdown", "metadata": {}}, {"execution_count": 44, "cell_type": "code", "source": "df_1.groupby(\"state\").apply(lambda x: type(x))", "outputs": [{"execution_count": 44, "output_type": "execute_result", "data": {"text/plain": "state\nMD \nVA \ndtype: object"}, "metadata": {}}], "metadata": {"scrolled": true, "collapsed": false, "trusted": true}}, {"execution_count": 45, "cell_type": "code", "source": "df_1.groupby(\"state\").apply(lambda x: x.sum())", "outputs": [{"execution_count": 45, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\nstate \nMD 8.1 MDMD 4029 12.1\nVA 15.3 VAVAVA 6039 6.0", "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
popstateyearunempl
state
MD 8.1 MDMD 4029 12.1
VA 15.3 VAVAVA 6039 6.0
\n
"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 46, "cell_type": "code", "source": "df_1.groupby([\"state\", \"year\"]).apply(lambda x: x.sum())", "outputs": [{"execution_count": 46, "output_type": "execute_result", "data": {"text/plain": " pop state year unempl\nstate year \nMD 2014 4.0 MD 2014 6.0\n 2015 4.1 MD 2015 6.1\nVA 2012 5.0 VA 2012 NaN\n 2013 5.1 VA 2013 NaN\n 2014 5.2 VA 2014 6.0", "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
popstateyearunempl
stateyear
MD2014 4.0 MD 2014 6.0
2015 4.1 MD 2015 6.1
VA2012 5.0 VA 2012 NaN
2013 5.1 VA 2013 NaN
2014 5.2 VA 2014 6.0
\n
"}, "metadata": {}}], "metadata": {"scrolled": true, "collapsed": false, "trusted": true}}, {"source": "## Plotting", "cell_type": "markdown", "metadata": {}}, {"execution_count": 47, "cell_type": "code", "source": "ser_2", "outputs": [{"execution_count": 47, "output_type": "execute_result", "data": {"text/plain": "a 0\nb 0\nc 2\nd -3\ne -5\ndtype: int64"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 48, "cell_type": "code", "source": "ser_2.plot()", "outputs": [{"execution_count": 48, "output_type": "execute_result", "data": {"text/plain": ""}, "metadata": {}}, {"output_type": "display_data", "data": {"image/png": "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\n", "text/plain": ""}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 49, "cell_type": "code", "source": "help(ser_2.plot)", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Help on method plot_series in module pandas.tools.plotting:\n\nplot_series(data, kind='line', ax=None, figsize=None, use_index=True, title=None, grid=None, legend=False, style=None, logx=False, logy=False, loglog=False, xticks=None, yticks=None, xlim=None, ylim=None, rot=None, fontsize=None, colormap=None, table=False, yerr=None, xerr=None, label=None, secondary_y=False, **kwds) method of pandas.core.series.Series instance\n Make plots of Series using matplotlib / pylab.\n \n Parameters\n ----------\n data : Series\n \n kind : str\n - 'line' : line plot (default)\n - 'bar' : vertical bar plot\n - 'barh' : horizontal bar plot\n - 'hist' : histogram\n - 'box' : boxplot\n - 'kde' : Kernel Density Estimation plot\n - 'density' : same as 'kde'\n - 'area' : area plot\n - 'pie' : pie plot\n \n ax : matplotlib axes object\n If not passed, uses gca()\n figsize : a tuple (width, height) in inches\n use_index : boolean, default True\n Use index as ticks for x axis\n title : string\n Title to use for the plot\n grid : boolean, default None (matlab style default)\n Axis grid lines\n legend : False/True/'reverse'\n Place legend on axis subplots\n style : list or dict\n matplotlib line style per column\n logx : boolean, default False\n Use log scaling on x axis\n logy : boolean, default False\n Use log scaling on y axis\n loglog : boolean, default False\n Use log scaling on both x and y axes\n xticks : sequence\n Values to use for the xticks\n yticks : sequence\n Values to use for the yticks\n xlim : 2-tuple/list\n ylim : 2-tuple/list\n rot : int, default None\n Rotation for ticks (xticks for vertical, yticks for horizontal plots)\n fontsize : int, default None\n Font size for xticks and yticks\n colormap : str or matplotlib colormap object, default None\n Colormap to select colors from. If string, load colormap with that name\n from matplotlib.\n colorbar : boolean, optional\n If True, plot colorbar (only relevant for 'scatter' and 'hexbin' plots)\n position : float\n Specify relative alignments for bar plot layout.\n From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center)\n layout : tuple (optional)\n (rows, columns) for the layout of the plot\n table : boolean, Series or DataFrame, default False\n If True, draw a table using the data in the DataFrame and the data will\n be transposed to meet matplotlib's default layout.\n If a Series or DataFrame is passed, use passed data to draw a table.\n yerr : DataFrame, Series, array-like, dict and str\n See :ref:`Plotting with Error Bars ` for detail.\n xerr : same types as yerr.\n label : label argument to provide to plot\n secondary_y : boolean or sequence of ints, default False\n If True then y-axis will be on the right\n mark_right : boolean, default True\n When using a secondary_y axis, automatically mark the column\n labels with \"(right)\" in the legend\n kwds : keywords\n Options to pass to matplotlib plotting method\n \n Returns\n -------\n axes : matplotlib.AxesSubplot or np.array of them\n \n Notes\n -----\n \n - See matplotlib documentation online for more on this subject\n - If `kind` = 'bar' or 'barh', you can specify relative alignments\n for bar plot layout by `position` keyword.\n From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center)\n\n"}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 50, "cell_type": "code", "source": "df_1.groupby(\"state\").mean()[[\"pop\", \"unempl\"]].plot(kind=\"bar\")", "outputs": [{"execution_count": 50, "output_type": "execute_result", "data": {"text/plain": ""}, "metadata": {}}, {"output_type": "display_data", "data": {"image/png": "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\nY/4fAeqPmhgA/rUAAAAASUVORK5CYII=\n", "text/plain": ""}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"source": "#####Exercises", "cell_type": "markdown", "metadata": {"collapsed": true}}, {"source": "1) Explore the boston housing dataset", "cell_type": "markdown", "metadata": {}}, {"execution_count": 51, "cell_type": "code", "source": "from sklearn.datasets import load_boston\nboston = load_boston()\ndataset = pd.DataFrame(boston.data, columns=boston[\"feature_names\"])\ndataset[\"MEDV\"] = boston[\"target\"]", "outputs": [], "metadata": {"collapsed": true, "trusted": true}}, {"execution_count": 52, "cell_type": "code", "source": "print boston[\"DESCR\"]", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Boston House Prices dataset\n\nNotes\n------\nData Set Characteristics: \n\n :Number of Instances: 506 \n\n :Number of Attributes: 13 numeric/categorical predictive\n \n :Median Value (attribute 14) is usually the target\n\n :Attribute Information (in order):\n - CRIM per capita crime rate by town\n - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\n - INDUS proportion of non-retail business acres per town\n - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\n - NOX nitric oxides concentration (parts per 10 million)\n - RM average number of rooms per dwelling\n - AGE proportion of owner-occupied units built prior to 1940\n - DIS weighted distances to five Boston employment centres\n - RAD index of accessibility to radial highways\n - TAX full-value property-tax rate per $10,000\n - PTRATIO pupil-teacher ratio by town\n - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\n - LSTAT % lower status of the population\n - MEDV Median value of owner-occupied homes in $1000's\n\n :Missing Attribute Values: None\n\n :Creator: Harrison, D. and Rubinfeld, D.L.\n\nThis is a copy of UCI ML housing dataset.\nhttp://archive.ics.uci.edu/ml/datasets/Housing\n\n\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\n\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\nprices and the demand for clean air', J. Environ. Economics & Management,\nvol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\n...', Wiley, 1980. N.B. Various transformations are used in the table on\npages 244-261 of the latter.\n\nThe Boston house-price data has been used in many machine learning papers that address regression\nproblems. \n \n**References**\n\n - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\n - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\n - many more! (see http://archive.ics.uci.edu/ml/datasets/Housing)\n\n"}], "metadata": {"scrolled": false, "collapsed": false, "trusted": true}}, {"execution_count": 53, "cell_type": "code", "source": "dataset", "outputs": [{"execution_count": 53, "output_type": "execute_result", "data": {"text/plain": " CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX \\\n0 0.00632 18.0 2.31 0 0.538 6.575 65.2 4.0900 1 296 \n1 0.02731 0.0 7.07 0 0.469 6.421 78.9 4.9671 2 242 \n2 0.02729 0.0 7.07 0 0.469 7.185 61.1 4.9671 2 242 \n3 0.03237 0.0 2.18 0 0.458 6.998 45.8 6.0622 3 222 \n4 0.06905 0.0 2.18 0 0.458 7.147 54.2 6.0622 3 222 \n5 0.02985 0.0 2.18 0 0.458 6.430 58.7 6.0622 3 222 \n6 0.08829 12.5 7.87 0 0.524 6.012 66.6 5.5605 5 311 \n7 0.14455 12.5 7.87 0 0.524 6.172 96.1 5.9505 5 311 \n8 0.21124 12.5 7.87 0 0.524 5.631 100.0 6.0821 5 311 \n9 0.17004 12.5 7.87 0 0.524 6.004 85.9 6.5921 5 311 \n10 0.22489 12.5 7.87 0 0.524 6.377 94.3 6.3467 5 311 \n11 0.11747 12.5 7.87 0 0.524 6.009 82.9 6.2267 5 311 \n12 0.09378 12.5 7.87 0 0.524 5.889 39.0 5.4509 5 311 \n13 0.62976 0.0 8.14 0 0.538 5.949 61.8 4.7075 4 307 \n14 0.63796 0.0 8.14 0 0.538 6.096 84.5 4.4619 4 307 \n15 0.62739 0.0 8.14 0 0.538 5.834 56.5 4.4986 4 307 \n16 1.05393 0.0 8.14 0 0.538 5.935 29.3 4.4986 4 307 \n17 0.78420 0.0 8.14 0 0.538 5.990 81.7 4.2579 4 307 \n18 0.80271 0.0 8.14 0 0.538 5.456 36.6 3.7965 4 307 \n19 0.72580 0.0 8.14 0 0.538 5.727 69.5 3.7965 4 307 \n20 1.25179 0.0 8.14 0 0.538 5.570 98.1 3.7979 4 307 \n21 0.85204 0.0 8.14 0 0.538 5.965 89.2 4.0123 4 307 \n22 1.23247 0.0 8.14 0 0.538 6.142 91.7 3.9769 4 307 \n23 0.98843 0.0 8.14 0 0.538 5.813 100.0 4.0952 4 307 \n24 0.75026 0.0 8.14 0 0.538 5.924 94.1 4.3996 4 307 \n25 0.84054 0.0 8.14 0 0.538 5.599 85.7 4.4546 4 307 \n26 0.67191 0.0 8.14 0 0.538 5.813 90.3 4.6820 4 307 \n27 0.95577 0.0 8.14 0 0.538 6.047 88.8 4.4534 4 307 \n28 0.77299 0.0 8.14 0 0.538 6.495 94.4 4.4547 4 307 \n29 1.00245 0.0 8.14 0 0.538 6.674 87.3 4.2390 4 307 \n.. ... ... ... ... ... ... ... ... ... ... \n476 4.87141 0.0 18.10 0 0.614 6.484 93.6 2.3053 24 666 \n477 15.02340 0.0 18.10 0 0.614 5.304 97.3 2.1007 24 666 \n478 10.23300 0.0 18.10 0 0.614 6.185 96.7 2.1705 24 666 \n479 14.33370 0.0 18.10 0 0.614 6.229 88.0 1.9512 24 666 \n480 5.82401 0.0 18.10 0 0.532 6.242 64.7 3.4242 24 666 \n481 5.70818 0.0 18.10 0 0.532 6.750 74.9 3.3317 24 666 \n482 5.73116 0.0 18.10 0 0.532 7.061 77.0 3.4106 24 666 \n483 2.81838 0.0 18.10 0 0.532 5.762 40.3 4.0983 24 666 \n484 2.37857 0.0 18.10 0 0.583 5.871 41.9 3.7240 24 666 \n485 3.67367 0.0 18.10 0 0.583 6.312 51.9 3.9917 24 666 \n486 5.69175 0.0 18.10 0 0.583 6.114 79.8 3.5459 24 666 \n487 4.83567 0.0 18.10 0 0.583 5.905 53.2 3.1523 24 666 \n488 0.15086 0.0 27.74 0 0.609 5.454 92.7 1.8209 4 711 \n489 0.18337 0.0 27.74 0 0.609 5.414 98.3 1.7554 4 711 \n490 0.20746 0.0 27.74 0 0.609 5.093 98.0 1.8226 4 711 \n491 0.10574 0.0 27.74 0 0.609 5.983 98.8 1.8681 4 711 \n492 0.11132 0.0 27.74 0 0.609 5.983 83.5 2.1099 4 711 \n493 0.17331 0.0 9.69 0 0.585 5.707 54.0 2.3817 6 391 \n494 0.27957 0.0 9.69 0 0.585 5.926 42.6 2.3817 6 391 \n495 0.17899 0.0 9.69 0 0.585 5.670 28.8 2.7986 6 391 \n496 0.28960 0.0 9.69 0 0.585 5.390 72.9 2.7986 6 391 \n497 0.26838 0.0 9.69 0 0.585 5.794 70.6 2.8927 6 391 \n498 0.23912 0.0 9.69 0 0.585 6.019 65.3 2.4091 6 391 \n499 0.17783 0.0 9.69 0 0.585 5.569 73.5 2.3999 6 391 \n500 0.22438 0.0 9.69 0 0.585 6.027 79.7 2.4982 6 391 \n501 0.06263 0.0 11.93 0 0.573 6.593 69.1 2.4786 1 273 \n502 0.04527 0.0 11.93 0 0.573 6.120 76.7 2.2875 1 273 \n503 0.06076 0.0 11.93 0 0.573 6.976 91.0 2.1675 1 273 \n504 0.10959 0.0 11.93 0 0.573 6.794 89.3 2.3889 1 273 \n505 0.04741 0.0 11.93 0 0.573 6.030 80.8 2.5050 1 273 \n\n PTRATIO B LSTAT MEDV \n0 15.3 396.90 4.98 24.0 \n1 17.8 396.90 9.14 21.6 \n2 17.8 392.83 4.03 34.7 \n3 18.7 394.63 2.94 33.4 \n4 18.7 396.90 5.33 36.2 \n5 18.7 394.12 5.21 28.7 \n6 15.2 395.60 12.43 22.9 \n7 15.2 396.90 19.15 27.1 \n8 15.2 386.63 29.93 16.5 \n9 15.2 386.71 17.10 18.9 \n10 15.2 392.52 20.45 15.0 \n11 15.2 396.90 13.27 18.9 \n12 15.2 390.50 15.71 21.7 \n13 21.0 396.90 8.26 20.4 \n14 21.0 380.02 10.26 18.2 \n15 21.0 395.62 8.47 19.9 \n16 21.0 386.85 6.58 23.1 \n17 21.0 386.75 14.67 17.5 \n18 21.0 288.99 11.69 20.2 \n19 21.0 390.95 11.28 18.2 \n20 21.0 376.57 21.02 13.6 \n21 21.0 392.53 13.83 19.6 \n22 21.0 396.90 18.72 15.2 \n23 21.0 394.54 19.88 14.5 \n24 21.0 394.33 16.30 15.6 \n25 21.0 303.42 16.51 13.9 \n26 21.0 376.88 14.81 16.6 \n27 21.0 306.38 17.28 14.8 \n28 21.0 387.94 12.80 18.4 \n29 21.0 380.23 11.98 21.0 \n.. ... ... ... ... \n476 20.2 396.21 18.68 16.7 \n477 20.2 349.48 24.91 12.0 \n478 20.2 379.70 18.03 14.6 \n479 20.2 383.32 13.11 21.4 \n480 20.2 396.90 10.74 23.0 \n481 20.2 393.07 7.74 23.7 \n482 20.2 395.28 7.01 25.0 \n483 20.2 392.92 10.42 21.8 \n484 20.2 370.73 13.34 20.6 \n485 20.2 388.62 10.58 21.2 \n486 20.2 392.68 14.98 19.1 \n487 20.2 388.22 11.45 20.6 \n488 20.1 395.09 18.06 15.2 \n489 20.1 344.05 23.97 7.0 \n490 20.1 318.43 29.68 8.1 \n491 20.1 390.11 18.07 13.6 \n492 20.1 396.90 13.35 20.1 \n493 19.2 396.90 12.01 21.8 \n494 19.2 396.90 13.59 24.5 \n495 19.2 393.29 17.60 23.1 \n496 19.2 396.90 21.14 19.7 \n497 19.2 396.90 14.10 18.3 \n498 19.2 396.90 12.92 21.2 \n499 19.2 395.77 15.10 17.5 \n500 19.2 396.90 14.33 16.8 \n501 21.0 391.99 9.67 22.4 \n502 21.0 396.90 9.08 20.6 \n503 21.0 396.90 5.64 23.9 \n504 21.0 393.45 6.48 22.0 \n505 21.0 396.90 7.88 11.9 \n\n[506 rows x 14 columns]", "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 \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATMEDV
0 0.00632 18.0 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 9.14 21.6
2 0.02729 0.0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 4.03 34.7
3 0.03237 0.0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 2.94 33.4
4 0.06905 0.0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 5.33 36.2
5 0.02985 0.0 2.18 0 0.458 6.430 58.7 6.0622 3 222 18.7 394.12 5.21 28.7
6 0.08829 12.5 7.87 0 0.524 6.012 66.6 5.5605 5 311 15.2 395.60 12.43 22.9
7 0.14455 12.5 7.87 0 0.524 6.172 96.1 5.9505 5 311 15.2 396.90 19.15 27.1
8 0.21124 12.5 7.87 0 0.524 5.631 100.0 6.0821 5 311 15.2 386.63 29.93 16.5
9 0.17004 12.5 7.87 0 0.524 6.004 85.9 6.5921 5 311 15.2 386.71 17.10 18.9
10 0.22489 12.5 7.87 0 0.524 6.377 94.3 6.3467 5 311 15.2 392.52 20.45 15.0
11 0.11747 12.5 7.87 0 0.524 6.009 82.9 6.2267 5 311 15.2 396.90 13.27 18.9
12 0.09378 12.5 7.87 0 0.524 5.889 39.0 5.4509 5 311 15.2 390.50 15.71 21.7
13 0.62976 0.0 8.14 0 0.538 5.949 61.8 4.7075 4 307 21.0 396.90 8.26 20.4
14 0.63796 0.0 8.14 0 0.538 6.096 84.5 4.4619 4 307 21.0 380.02 10.26 18.2
15 0.62739 0.0 8.14 0 0.538 5.834 56.5 4.4986 4 307 21.0 395.62 8.47 19.9
16 1.05393 0.0 8.14 0 0.538 5.935 29.3 4.4986 4 307 21.0 386.85 6.58 23.1
17 0.78420 0.0 8.14 0 0.538 5.990 81.7 4.2579 4 307 21.0 386.75 14.67 17.5
18 0.80271 0.0 8.14 0 0.538 5.456 36.6 3.7965 4 307 21.0 288.99 11.69 20.2
19 0.72580 0.0 8.14 0 0.538 5.727 69.5 3.7965 4 307 21.0 390.95 11.28 18.2
20 1.25179 0.0 8.14 0 0.538 5.570 98.1 3.7979 4 307 21.0 376.57 21.02 13.6
21 0.85204 0.0 8.14 0 0.538 5.965 89.2 4.0123 4 307 21.0 392.53 13.83 19.6
22 1.23247 0.0 8.14 0 0.538 6.142 91.7 3.9769 4 307 21.0 396.90 18.72 15.2
23 0.98843 0.0 8.14 0 0.538 5.813 100.0 4.0952 4 307 21.0 394.54 19.88 14.5
24 0.75026 0.0 8.14 0 0.538 5.924 94.1 4.3996 4 307 21.0 394.33 16.30 15.6
25 0.84054 0.0 8.14 0 0.538 5.599 85.7 4.4546 4 307 21.0 303.42 16.51 13.9
26 0.67191 0.0 8.14 0 0.538 5.813 90.3 4.6820 4 307 21.0 376.88 14.81 16.6
27 0.95577 0.0 8.14 0 0.538 6.047 88.8 4.4534 4 307 21.0 306.38 17.28 14.8
28 0.77299 0.0 8.14 0 0.538 6.495 94.4 4.4547 4 307 21.0 387.94 12.80 18.4
29 1.00245 0.0 8.14 0 0.538 6.674 87.3 4.2390 4 307 21.0 380.23 11.98 21.0
.............................................
476 4.87141 0.0 18.10 0 0.614 6.484 93.6 2.3053 24 666 20.2 396.21 18.68 16.7
477 15.02340 0.0 18.10 0 0.614 5.304 97.3 2.1007 24 666 20.2 349.48 24.91 12.0
478 10.23300 0.0 18.10 0 0.614 6.185 96.7 2.1705 24 666 20.2 379.70 18.03 14.6
479 14.33370 0.0 18.10 0 0.614 6.229 88.0 1.9512 24 666 20.2 383.32 13.11 21.4
480 5.82401 0.0 18.10 0 0.532 6.242 64.7 3.4242 24 666 20.2 396.90 10.74 23.0
481 5.70818 0.0 18.10 0 0.532 6.750 74.9 3.3317 24 666 20.2 393.07 7.74 23.7
482 5.73116 0.0 18.10 0 0.532 7.061 77.0 3.4106 24 666 20.2 395.28 7.01 25.0
483 2.81838 0.0 18.10 0 0.532 5.762 40.3 4.0983 24 666 20.2 392.92 10.42 21.8
484 2.37857 0.0 18.10 0 0.583 5.871 41.9 3.7240 24 666 20.2 370.73 13.34 20.6
485 3.67367 0.0 18.10 0 0.583 6.312 51.9 3.9917 24 666 20.2 388.62 10.58 21.2
486 5.69175 0.0 18.10 0 0.583 6.114 79.8 3.5459 24 666 20.2 392.68 14.98 19.1
487 4.83567 0.0 18.10 0 0.583 5.905 53.2 3.1523 24 666 20.2 388.22 11.45 20.6
488 0.15086 0.0 27.74 0 0.609 5.454 92.7 1.8209 4 711 20.1 395.09 18.06 15.2
489 0.18337 0.0 27.74 0 0.609 5.414 98.3 1.7554 4 711 20.1 344.05 23.97 7.0
490 0.20746 0.0 27.74 0 0.609 5.093 98.0 1.8226 4 711 20.1 318.43 29.68 8.1
491 0.10574 0.0 27.74 0 0.609 5.983 98.8 1.8681 4 711 20.1 390.11 18.07 13.6
492 0.11132 0.0 27.74 0 0.609 5.983 83.5 2.1099 4 711 20.1 396.90 13.35 20.1
493 0.17331 0.0 9.69 0 0.585 5.707 54.0 2.3817 6 391 19.2 396.90 12.01 21.8
494 0.27957 0.0 9.69 0 0.585 5.926 42.6 2.3817 6 391 19.2 396.90 13.59 24.5
495 0.17899 0.0 9.69 0 0.585 5.670 28.8 2.7986 6 391 19.2 393.29 17.60 23.1
496 0.28960 0.0 9.69 0 0.585 5.390 72.9 2.7986 6 391 19.2 396.90 21.14 19.7
497 0.26838 0.0 9.69 0 0.585 5.794 70.6 2.8927 6 391 19.2 396.90 14.10 18.3
498 0.23912 0.0 9.69 0 0.585 6.019 65.3 2.4091 6 391 19.2 396.90 12.92 21.2
499 0.17783 0.0 9.69 0 0.585 5.569 73.5 2.3999 6 391 19.2 395.77 15.10 17.5
500 0.22438 0.0 9.69 0 0.585 6.027 79.7 2.4982 6 391 19.2 396.90 14.33 16.8
501 0.06263 0.0 11.93 0 0.573 6.593 69.1 2.4786 1 273 21.0 391.99 9.67 22.4
502 0.04527 0.0 11.93 0 0.573 6.120 76.7 2.2875 1 273 21.0 396.90 9.08 20.6
503 0.06076 0.0 11.93 0 0.573 6.976 91.0 2.1675 1 273 21.0 396.90 5.64 23.9
504 0.10959 0.0 11.93 0 0.573 6.794 89.3 2.3889 1 273 21.0 393.45 6.48 22.0
505 0.04741 0.0 11.93 0 0.573 6.030 80.8 2.5050 1 273 21.0 396.90 7.88 11.9
\n

506 rows \u00d7 14 columns

\n
"}, "metadata": {}}], "metadata": {"scrolled": false, "collapsed": false, "trusted": true}}, {"execution_count": null, "cell_type": "code", "source": "", "outputs": [], "metadata": {"collapsed": true, "trusted": true}}], "nbformat": 4, "metadata": {"kernelspec": {"display_name": "Python 2", "name": "python2", "language": "python"}, "language_info": {"mimetype": "text/x-python", "nbconvert_exporter": "python", "version": "2.7.9", "name": "python", "file_extension": ".py", "pygments_lexer": "ipython2", "codemirror_mode": {"version": 2, "name": "ipython"}}}} -------------------------------------------------------------------------------- /slides/Telemetry Onboarding 2.0.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/telemetry-onboarding/b2ff334fcc20809548aa688cd1b04b540546514f/slides/Telemetry Onboarding 2.0.key -------------------------------------------------------------------------------- /slides/Telemetry Onboarding 2.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/telemetry-onboarding/b2ff334fcc20809548aa688cd1b04b540546514f/slides/Telemetry Onboarding 2.0.pdf -------------------------------------------------------------------------------- /slides/Telemetry Onboarding.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/telemetry-onboarding/b2ff334fcc20809548aa688cd1b04b540546514f/slides/Telemetry Onboarding.pdf -------------------------------------------------------------------------------- /slides/Telemetry Onboarding.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/telemetry-onboarding/b2ff334fcc20809548aa688cd1b04b540546514f/slides/Telemetry Onboarding.pptx --------------------------------------------------------------------------------