{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n",
"\n",
"*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n",
"\n",
"*No changes were made to the contents of this notebook from the original.*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"< [Computation on Arrays: Broadcasting](02.05-Computation-on-arrays-broadcasting.ipynb) | [Contents](Index.ipynb) | [Fancy Indexing](02.07-Fancy-Indexing.ipynb) >"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Comparisons, Masks, and Boolean Logic"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This section covers the use of Boolean masks to examine and manipulate values within NumPy arrays.\n",
"Masking comes up when you want to extract, modify, count, or otherwise manipulate values in an array based on some criterion: for example, you might wish to count all values greater than a certain value, or perhaps remove all outliers that are above some threshold.\n",
"In NumPy, Boolean masking is often the most efficient way to accomplish these types of tasks."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: Counting Rainy Days\n",
"\n",
"Imagine you have a series of data that represents the amount of precipitation each day for a year in a given city.\n",
"For example, here we'll load the daily rainfall statistics for the city of Seattle in 2014, using Pandas (which is covered in more detail in [Chapter 3](03.00-Introduction-to-Pandas.ipynb)):"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(365,)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"# use pandas to extract rainfall inches as a NumPy array\n",
"rainfall = pd.read_csv('data/Seattle2014.csv')['PRCP'].values\n",
"inches = rainfall / 254 # 1/10mm -> inches\n",
"inches.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The array contains 365 values, giving daily rainfall in inches from January 1 to December 31, 2014.\n",
"\n",
"As a first quick visualization, let's look at the histogram of rainy days, which was generated using Matplotlib (we will explore this tool more fully in [Chapter 4](04.00-Introduction-To-Matplotlib.ipynb)):"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"import seaborn; seaborn.set() # set plot styles"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"