{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Data Wrangling: Clean, Transform, Merge, Reshape" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from __future__ import division\n", "from numpy.random import randn\n", "import numpy as np\n", "import os\n", "import matplotlib.pyplot as plt\n", "np.random.seed(12345)\n", "plt.rc('figure', figsize=(10, 6))\n", "from pandas import Series, DataFrame\n", "import pandas\n", "import pandas as pd\n", "np.set_printoptions(precision=4, threshold=500)\n", "pd.options.display.max_rows = 100" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Combining and merging data sets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Database-style DataFrame merges" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],\n", " 'data1': range(7)})\n", "df2 = DataFrame({'key': ['a', 'b', 'd'],\n", " 'data2': range(3)})\n", "df1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(df1, df2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(df1, df2, on='key')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df3 = DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],\n", " 'data1': range(7)})\n", "df4 = DataFrame({'rkey': ['a', 'b', 'd'],\n", " 'data2': range(3)})\n", "pd.merge(df3, df4, left_on='lkey', right_on='rkey')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(df1, df2, how='outer')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],\n", " 'data1': range(6)})\n", "df2 = DataFrame({'key': ['a', 'b', 'a', 'b', 'd'],\n", " 'data2': range(5)})" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(df1, df2, on='key', how='left')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(df1, df2, how='inner')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left = DataFrame({'key1': ['foo', 'foo', 'bar'],\n", " 'key2': ['one', 'two', 'one'],\n", " 'lval': [1, 2, 3]})\n", "right = DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],\n", " 'key2': ['one', 'one', 'one', 'two'],\n", " 'rval': [4, 5, 6, 7]})\n", "pd.merge(left, right, on=['key1', 'key2'], how='outer')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(left, right, on='key1')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(left, right, on='key1', suffixes=('_left', '_right'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Merging on index" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left1 = DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],\n", " 'value': range(6)})\n", "right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "right1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(left1, right1, left_on='key', right_index=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(left1, right1, left_on='key', right_index=True, how='outer')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "lefth = DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],\n", " 'key2': [2000, 2001, 2002, 2001, 2002],\n", " 'data': np.arange(5.)})\n", "righth = DataFrame(np.arange(12).reshape((6, 2)),\n", " index=[['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'],\n", " [2001, 2000, 2000, 2000, 2001, 2002]],\n", " columns=['event1', 'event2'])\n", "lefth" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "righth" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(lefth, righth, left_on=['key1', 'key2'],\n", " right_index=True, how='outer')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left2 = DataFrame([[1., 2.], [3., 4.], [5., 6.]], index=['a', 'c', 'e'],\n", " columns=['Ohio', 'Nevada'])\n", "right2 = DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],\n", " index=['b', 'c', 'd', 'e'], columns=['Missouri', 'Alabama'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "right2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.merge(left2, right2, how='outer', left_index=True, right_index=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left2.join(right2, how='outer')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left1.join(right1, on='key')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "another = DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],\n", " index=['a', 'c', 'e', 'f'], columns=['New York', 'Oregon'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left2.join([right2, another])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "left2.join([right2, another], how='outer')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Concatenating along an axis" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.arange(12).reshape((3, 4))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.concatenate([arr, arr], axis=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "s1 = Series([0, 1], index=['a', 'b'])\n", "s2 = Series([2, 3, 4], index=['c', 'd', 'e'])\n", "s3 = Series([5, 6], index=['f', 'g'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([s1, s2, s3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([s1, s2, s3], axis=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "s4 = pd.concat([s1 * 5, s3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([s1, s4], axis=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([s1, s4], axis=1, join='inner')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Much more on the unstack function later\n", "result.unstack()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1 = DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],\n", " columns=['one', 'two'])\n", "df2 = DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],\n", " columns=['three', 'four'])\n", "pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat({'level1': df1, 'level2': df2}, axis=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],\n", " names=['upper', 'lower'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1 = DataFrame(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd'])\n", "df2 = DataFrame(np.random.randn(2, 3), columns=['b', 'd', 'a'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.concat([df1, df2], ignore_index=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Combining data with overlap" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],\n", " index=['f', 'e', 'd', 'c', 'b', 'a'])\n", "b = Series(np.arange(len(a), dtype=np.float64),\n", " index=['f', 'e', 'd', 'c', 'b', 'a'])\n", "b[-1] = np.nan" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.where(pd.isnull(a), b, a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "b[:-2].combine_first(a[2:])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df1 = DataFrame({'a': [1., np.nan, 5., np.nan],\n", " 'b': [np.nan, 2., np.nan, 6.],\n", " 'c': range(2, 18, 4)})\n", "df2 = DataFrame({'a': [5., 4., np.nan, 3., 7.],\n", " 'b': [np.nan, 3., 4., 6., 8.]})\n", "df1.combine_first(df2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reshaping and pivoting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Reshaping with hierarchical indexing" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = DataFrame(np.arange(6).reshape((2, 3)),\n", " index=pd.Index(['Ohio', 'Colorado'], name='state'),\n", " columns=pd.Index(['one', 'two', 'three'], name='number'))\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result = data.stack()\n", "result" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result.unstack()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result.unstack(0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result.unstack('state')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "s1 = Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd'])\n", "s2 = Series([4, 5, 6], index=['c', 'd', 'e'])\n", "data2 = pd.concat([s1, s2], keys=['one', 'two'])\n", "data2.unstack()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data2.unstack().stack()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data2.unstack().stack(dropna=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df = DataFrame({'left': result, 'right': result + 5},\n", " columns=pd.Index(['left', 'right'], name='side'))\n", "df" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df.unstack('state')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df.unstack('state').stack('side')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pivoting \"long\" to \"wide\" format" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = pd.read_csv('ch07/macrodata.csv')\n", "periods = pd.PeriodIndex(year=data.year, quarter=data.quarter, name='date')\n", "data = DataFrame(data.to_records(),\n", " columns=pd.Index(['realgdp', 'infl', 'unemp'], name='item'),\n", " index=periods.to_timestamp('D', 'end'))\n", "\n", "ldata = data.stack().reset_index().rename(columns={0: 'value'})\n", "wdata = ldata.pivot('date', 'item', 'value')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ldata[:10]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pivoted = ldata.pivot('date', 'item', 'value')\n", "pivoted.head()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ldata['value2'] = np.random.randn(len(ldata))\n", "ldata[:10]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pivoted = ldata.pivot('date', 'item')\n", "pivoted[:5]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pivoted['value'][:5]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "unstacked = ldata.set_index(['date', 'item']).unstack('item')\n", "unstacked[:7]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data transformation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Removing duplicates" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = DataFrame({'k1': ['one'] * 3 + ['two'] * 4,\n", " 'k2': [1, 1, 2, 3, 3, 4, 4]})\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.duplicated()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.drop_duplicates()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data['v1'] = range(7)\n", "data.drop_duplicates(['k1'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.drop_duplicates(['k1', 'k2'], take_last=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Transforming data using a function or mapping" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami',\n", " 'corned beef', 'Bacon', 'pastrami', 'honey ham',\n", " 'nova lox'],\n", " 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "meat_to_animal = {\n", " 'bacon': 'pig',\n", " 'pulled pork': 'pig',\n", " 'pastrami': 'cow',\n", " 'corned beef': 'cow',\n", " 'honey ham': 'pig',\n", " 'nova lox': 'salmon'\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data['animal'] = data['food'].map(str.lower).map(meat_to_animal)\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data['food'].map(lambda x: meat_to_animal[x.lower()])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Replacing values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = Series([1., -999., 2., -999., -1000., 3.])\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.replace(-999, np.nan)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.replace([-999, -1000], np.nan)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.replace([-999, -1000], [np.nan, 0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.replace({-999: np.nan, -1000: 0})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Renaming axis indexes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = DataFrame(np.arange(12).reshape((3, 4)),\n", " index=['Ohio', 'Colorado', 'New York'],\n", " columns=['one', 'two', 'three', 'four'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.index.map(str.upper)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.index = data.index.map(str.upper)\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.rename(index=str.title, columns=str.upper)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.rename(index={'OHIO': 'INDIANA'},\n", " columns={'three': 'peekaboo'})" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Always returns a reference to a DataFrame\n", "_ = data.rename(index={'OHIO': 'INDIANA'}, inplace=True)\n", "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Discretization and binning" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "bins = [18, 25, 35, 60, 100]\n", "cats = pd.cut(ages, bins)\n", "cats" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "cats.labels" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "cats.levels" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.value_counts(cats)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.cut(ages, [18, 26, 36, 61, 100], right=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']\n", "pd.cut(ages, bins, labels=group_names)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = np.random.rand(20)\n", "pd.cut(data, 4, precision=2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = np.random.randn(1000) # Normally distributed\n", "cats = pd.qcut(data, 4) # Cut into quartiles\n", "cats" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.value_counts(cats)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Detecting and filtering outliers" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.random.seed(12345)\n", "data = DataFrame(np.random.randn(1000, 4))\n", "data.describe()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "col = data[3]\n", "col[np.abs(col) > 3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data[(np.abs(data) > 3).any(1)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data[np.abs(data) > 3] = np.sign(data) * 3\n", "data.describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Permutation and random sampling" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df = DataFrame(np.arange(5 * 4).reshape((5, 4)))\n", "sampler = np.random.permutation(5)\n", "sampler" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df.take(sampler)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df.take(np.random.permutation(len(df))[:3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "bag = np.array([5, 7, -1, 6, 4])\n", "sampler = np.random.randint(0, len(bag), size=10)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "sampler" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "draws = bag.take(sampler)\n", "draws" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Computing indicator / dummy variables" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "df = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],\n", " 'data1': range(6)})\n", "pd.get_dummies(df['key'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "dummies = pd.get_dummies(df['key'], prefix='key')\n", "df_with_dummy = df[['data1']].join(dummies)\n", "df_with_dummy" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mnames = ['movie_id', 'title', 'genres']\n", "movies = pd.read_table('ch02/movielens/movies.dat', sep='::', header=None,\n", " names=mnames)\n", "movies[:10]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "genre_iter = (set(x.split('|')) for x in movies.genres)\n", "genres = sorted(set.union(*genre_iter))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "dummies = DataFrame(np.zeros((len(movies), len(genres))), columns=genres)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "for i, gen in enumerate(movies.genres):\n", " dummies.ix[i, gen.split('|')] = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "movies_windic = movies.join(dummies.add_prefix('Genre_'))\n", "movies_windic.ix[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.random.seed(12345)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "values = np.random.rand(10)\n", "values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "bins = [0, 0.2, 0.4, 0.6, 0.8, 1]\n", "pd.get_dummies(pd.cut(values, bins))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## String manipulation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### String object methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val = 'a,b, guido'\n", "val.split(',')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pieces = [x.strip() for x in val.split(',')]\n", "pieces" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "first, second, third = pieces\n", "first + '::' + second + '::' + third" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "'::'.join(pieces)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "'guido' in val" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val.index(',')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val.find(':')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val.index(':')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val.count(',')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val.replace(',', '::')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "val.replace(',', '')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Regular expressions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import re\n", "text = \"foo bar\\t baz \\tqux\"\n", "re.split('\\s+', text)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "regex = re.compile('\\s+')\n", "regex.split(text)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "regex.findall(text)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "text = \"\"\"Dave dave@google.com\n", "Steve steve@gmail.com\n", "Rob rob@gmail.com\n", "Ryan ryan@yahoo.com\n", "\"\"\"\n", "pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}'\n", "\n", "# re.IGNORECASE makes the regex case-insensitive\n", "regex = re.compile(pattern, flags=re.IGNORECASE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "regex.findall(text)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "m = regex.search(text)\n", "m" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "text[m.start():m.end()]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(regex.match(text))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(regex.sub('REDACTED', text))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})'\n", "regex = re.compile(pattern, flags=re.IGNORECASE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "m = regex.match('wesm@bright.net')\n", "m.groups()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "regex.findall(text)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(regex.sub(r'Username: \\1, Domain: \\2, Suffix: \\3', text))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "regex = re.compile(r\"\"\"\n", " (?P[A-Z0-9._%+-]+)\n", " @\n", " (?P[A-Z0-9.-]+)\n", " \\.\n", " (?P[A-Z]{2,4})\"\"\", flags=re.IGNORECASE|re.VERBOSE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "m = regex.match('wesm@bright.net')\n", "m.groupdict()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vectorized string functions in pandas" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com',\n", " 'Rob': 'rob@gmail.com', 'Wes': np.nan}\n", "data = Series(data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.isnull()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.str.contains('gmail')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pattern" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.str.findall(pattern, flags=re.IGNORECASE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "matches = data.str.match(pattern, flags=re.IGNORECASE)\n", "matches" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "matches.str.get(1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "matches.str[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data.str[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example: USDA Food Database" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "{\n", " \"id\": 21441,\n", " \"description\": \"KENTUCKY FRIED CHICKEN, Fried Chicken, EXTRA CRISPY,\n", "Wing, meat and skin with breading\",\n", " \"tags\": [\"KFC\"],\n", " \"manufacturer\": \"Kentucky Fried Chicken\",\n", " \"group\": \"Fast Foods\",\n", " \"portions\": [\n", " {\n", " \"amount\": 1,\n", " \"unit\": \"wing, with skin\",\n", " \"grams\": 68.0\n", " },\n", "\n", " ...\n", " ],\n", " \"nutrients\": [\n", " {\n", " \"value\": 20.8,\n", " \"units\": \"g\",\n", " \"description\": \"Protein\",\n", " \"group\": \"Composition\"\n", " },\n", "\n", " ...\n", " ]\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import json\n", "db = json.load(open('ch07/foods-2011-10-03.json'))\n", "len(db)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "db[0].keys()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "db[0]['nutrients'][0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nutrients = DataFrame(db[0]['nutrients'])\n", "nutrients[:7]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "info_keys = ['description', 'group', 'id', 'manufacturer']\n", "info = DataFrame(db, columns=info_keys)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "info[:5]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "info" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "pd.value_counts(info.group)[:10]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nutrients = []\n", "\n", "for rec in db:\n", " fnuts = DataFrame(rec['nutrients'])\n", " fnuts['id'] = rec['id']\n", " nutrients.append(fnuts)\n", "\n", "nutrients = pd.concat(nutrients, ignore_index=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nutrients" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nutrients.duplicated().sum()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nutrients = nutrients.drop_duplicates()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "col_mapping = {'description' : 'food',\n", " 'group' : 'fgroup'}\n", "info = info.rename(columns=col_mapping, copy=False)\n", "info" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "col_mapping = {'description' : 'nutrient',\n", " 'group' : 'nutgroup'}\n", "nutrients = nutrients.rename(columns=col_mapping, copy=False)\n", "nutrients" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ndata = pd.merge(nutrients, info, on='id', how='outer')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ndata" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ndata.ix[30000]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result = ndata.groupby(['nutrient', 'fgroup'])['value'].quantile(0.5)\n", "result['Zinc, Zn'].order().plot(kind='barh')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "by_nutrient = ndata.groupby(['nutgroup', 'nutrient'])\n", "\n", "get_maximum = lambda x: x.xs(x.value.idxmax())\n", "get_minimum = lambda x: x.xs(x.value.idxmin())\n", "\n", "max_foods = by_nutrient.apply(get_maximum)[['value', 'food']]\n", "\n", "# make the food a little smaller\n", "max_foods.food = max_foods.food.str[:50]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "max_foods.ix['Amino Acids']['food']" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }