Skip to content

Instantly share code, notes, and snippets.

@gchoueiter
Created July 30, 2013 01:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gchoueiter/6109402 to your computer and use it in GitHub Desktop.
Save gchoueiter/6109402 to your computer and use it in GitHub Desktop.
Longer version of pandas lightning tutorial
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "Pandas Lightning Tutorial"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"About me"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Ghinwa Choueiter, pronounced (Rinwa Shweyter).\n",
"* Data Scientist and Machine Learning Engineer at DataXu.\n",
"* Studied speech science at MIT.\n",
"* When not working or studying, I love reading, biking, hiking, swimming, cooking. "
]
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"What are Pandas\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Pandas is a python library with rich and easy-to-use tools and data structures for data analysis, manipulation, and modeling.\n",
"* Pandas was developed by Wes McKinney starting in 2008.\n",
"* Pandas derives from Panel Data, a common term to denote multi-dimensional data often observed in finance and econometrics.\n",
"* Great reference: Python for Data Analysis by Wes McKinney.\n",
"* The two most common data structures used in Pandas are:\n",
" * Series: a 1-dimensional labeled data array. \n",
" * DataFrames: a 2-dimensional labeled data structure with columns of potentially different types. \n",
"* In this talk, we focus on DataFrames and we use the MovieLens 1M Data Set and US Baby Names 1880-2010 to illustrate some examples."
]
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"5 Cool Things to Know About Pandas"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"1. Easy to load tabular data"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import pandas as pd\n",
"from pandas import DataFrame, Series\n",
"\n",
"# Create DataFrames from dicts\n",
"data = {'calories': [100,150,120],\n",
" 'fruit': ['apple','orange','banana']}\n",
"\n",
"df = DataFrame(data)\n",
"print(df)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
" calories fruit\n",
"0 100 apple\n",
"1 150 orange\n",
"2 120 banana\n"
]
}
],
"prompt_number": 69
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Create DataFrames from Series\n",
"data = {'calories': Series([100,150,120,140], index=['a','b','c','d']),\n",
" 'fruit': Series(['apple','orange','banana'],index=['a','b','c'])}\n",
"df = DataFrame(data)\n",
"\n",
"print(df)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
" calories fruit\n",
"a 100 apple\n",
"b 150 orange\n",
"c 120 banana\n",
"d 140 NaN\n"
]
}
],
"prompt_number": 70
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.index"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 71,
"text": [
"Index([a, b, c, d], dtype=object)"
]
}
],
"prompt_number": 71
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.columns"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 72,
"text": [
"Index([calories, fruit], dtype=object)"
]
}
],
"prompt_number": 72
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# read from file\n",
"unames = ['user_id', 'gender', 'age', 'occupation', 'zip'] \n",
"users = pd.read_table('/Users/gchoueiter/Documents/Classes/panda/pydata-book/ch02/movielens/users.dat', \n",
" sep='::', header=None,names=unames)\n",
"\n",
"rnames = ['user_id', 'movie_id', 'rating', 'timestamp']\n",
"ratings = pd.read_table('/Users/gchoueiter/Documents/Classes/panda/pydata-book/ch02/movielens/ratings.dat', \n",
" sep='::', header=None,names=rnames)\n",
"\n",
"mnames = ['movie_id', 'title', 'genres']\n",
"movies = pd.read_table('/Users/gchoueiter/Documents/Classes/panda/pydata-book/ch02/movielens/movies.dat', \n",
" sep='::', header=None,names=mnames)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 73
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"users[:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>user_id</th>\n",
" <th>gender</th>\n",
" <th>age</th>\n",
" <th>occupation</th>\n",
" <th>zip</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 1</td>\n",
" <td> F</td>\n",
" <td> 1</td>\n",
" <td> 10</td>\n",
" <td> 48067</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 2</td>\n",
" <td> M</td>\n",
" <td> 56</td>\n",
" <td> 16</td>\n",
" <td> 70072</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 3</td>\n",
" <td> M</td>\n",
" <td> 25</td>\n",
" <td> 15</td>\n",
" <td> 55117</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 4</td>\n",
" <td> M</td>\n",
" <td> 45</td>\n",
" <td> 7</td>\n",
" <td> 02460</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 5</td>\n",
" <td> M</td>\n",
" <td> 25</td>\n",
" <td> 20</td>\n",
" <td> 55455</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 74,
"text": [
" user_id gender age occupation zip\n",
"0 1 F 1 10 48067\n",
"1 2 M 56 16 70072\n",
"2 3 M 25 15 55117\n",
"3 4 M 45 7 02460\n",
"4 5 M 25 20 55455"
]
}
],
"prompt_number": 74
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ratings[:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>user_id</th>\n",
" <th>movie_id</th>\n",
" <th>rating</th>\n",
" <th>timestamp</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 1</td>\n",
" <td> 1193</td>\n",
" <td> 5</td>\n",
" <td> 978300760</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 1</td>\n",
" <td> 661</td>\n",
" <td> 3</td>\n",
" <td> 978302109</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 1</td>\n",
" <td> 914</td>\n",
" <td> 3</td>\n",
" <td> 978301968</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 1</td>\n",
" <td> 3408</td>\n",
" <td> 4</td>\n",
" <td> 978300275</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1</td>\n",
" <td> 2355</td>\n",
" <td> 5</td>\n",
" <td> 978824291</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 75,
"text": [
" user_id movie_id rating timestamp\n",
"0 1 1193 5 978300760\n",
"1 1 661 3 978302109\n",
"2 1 914 3 978301968\n",
"3 1 3408 4 978300275\n",
"4 1 2355 5 978824291"
]
}
],
"prompt_number": 75
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"movies[:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>movie_id</th>\n",
" <th>title</th>\n",
" <th>genres</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 1</td>\n",
" <td> Toy Story (1995)</td>\n",
" <td> Animation|Children's|Comedy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 2</td>\n",
" <td> Jumanji (1995)</td>\n",
" <td> Adventure|Children's|Fantasy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 3</td>\n",
" <td> Grumpier Old Men (1995)</td>\n",
" <td> Comedy|Romance</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 4</td>\n",
" <td> Waiting to Exhale (1995)</td>\n",
" <td> Comedy|Drama</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 5</td>\n",
" <td> Father of the Bride Part II (1995)</td>\n",
" <td> Comedy</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 76,
"text": [
" movie_id title genres\n",
"0 1 Toy Story (1995) Animation|Children's|Comedy\n",
"1 2 Jumanji (1995) Adventure|Children's|Fantasy\n",
"2 3 Grumpier Old Men (1995) Comedy|Romance\n",
"3 4 Waiting to Exhale (1995) Comedy|Drama\n",
"4 5 Father of the Bride Part II (1995) Comedy"
]
}
],
"prompt_number": 76
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Reading csv is also easy.\n",
"names_cols = ['name','sex','births']\n",
"names = pd.read_csv('/Users/gchoueiter/Documents/Classes/panda/pydata-book/ch02/names/yob1880.txt',names=names_cols)\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 77
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"names[:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>name</th>\n",
" <th>sex</th>\n",
" <th>births</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> Mary</td>\n",
" <td> F</td>\n",
" <td> 7065</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> Anna</td>\n",
" <td> F</td>\n",
" <td> 2604</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> Emma</td>\n",
" <td> F</td>\n",
" <td> 2003</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> Elizabeth</td>\n",
" <td> F</td>\n",
" <td> 1939</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> Minnie</td>\n",
" <td> F</td>\n",
" <td> 1746</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 78,
"text": [
" name sex births\n",
"0 Mary F 7065\n",
"1 Anna F 2604\n",
"2 Emma F 2003\n",
"3 Elizabeth F 1939\n",
"4 Minnie F 1746"
]
}
],
"prompt_number": 78
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"2. Easy to Access, Add, and Delete Data"
]
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"A. Data Access"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Access by column(s)\n",
"users['user_id'][:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 79,
"text": [
"0 1\n",
"1 2\n",
"2 3\n",
"3 4\n",
"4 5\n",
"Name: user_id"
]
}
],
"prompt_number": 79
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Columns can be accessed via the dot notation as well\n",
"users.user_id[:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 80,
"text": [
"0 1\n",
"1 2\n",
"2 3\n",
"3 4\n",
"4 5\n",
"Name: user_id"
]
}
],
"prompt_number": 80
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"users[['user_id','gender']][:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>user_id</th>\n",
" <th>gender</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 1</td>\n",
" <td> F</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 2</td>\n",
" <td> M</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 3</td>\n",
" <td> M</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 4</td>\n",
" <td> M</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 5</td>\n",
" <td> M</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 81,
"text": [
" user_id gender\n",
"0 1 F\n",
"1 2 M\n",
"2 3 M\n",
"3 4 M\n",
"4 5 M"
]
}
],
"prompt_number": 81
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Access by row(s)\n",
"users.ix[2:3]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>user_id</th>\n",
" <th>gender</th>\n",
" <th>age</th>\n",
" <th>occupation</th>\n",
" <th>zip</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 3</td>\n",
" <td> M</td>\n",
" <td> 25</td>\n",
" <td> 15</td>\n",
" <td> 55117</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 4</td>\n",
" <td> M</td>\n",
" <td> 45</td>\n",
" <td> 7</td>\n",
" <td> 02460</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 82,
"text": [
" user_id gender age occupation zip\n",
"2 3 M 25 15 55117\n",
"3 4 M 45 7 02460"
]
}
],
"prompt_number": 82
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Filtering on rows and columns\n",
"users.ix[2:4,['user_id','gender']]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>user_id</th>\n",
" <th>gender</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 3</td>\n",
" <td> M</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 4</td>\n",
" <td> M</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 5</td>\n",
" <td> M</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 83,
"text": [
" user_id gender\n",
"2 3 M\n",
"3 4 M\n",
"4 5 M"
]
}
],
"prompt_number": 83
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Rows can be accessed by names and not just integer indices\n",
"df.ix['a':'c']"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>a</th>\n",
" <td> 100</td>\n",
" <td> apple</td>\n",
" </tr>\n",
" <tr>\n",
" <th>b</th>\n",
" <td> 150</td>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>c</th>\n",
" <td> 120</td>\n",
" <td> banana</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 84,
"text": [
" calories fruit\n",
"a 100 apple\n",
"b 150 orange\n",
"c 120 banana"
]
}
],
"prompt_number": 84
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# ix can also be used with a filter\n",
"df.ix[df.calories > 100]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>b</th>\n",
" <td> 150</td>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>c</th>\n",
" <td> 120</td>\n",
" <td> banana</td>\n",
" </tr>\n",
" <tr>\n",
" <th>d</th>\n",
" <td> 140</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 85,
"text": [
" calories fruit\n",
"b 150 orange\n",
"c 120 banana\n",
"d 140 NaN"
]
}
],
"prompt_number": 85
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"B. Add Data"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Adding column\n",
"df['color'] = ['red','orange','yellow','pink']\n",
"\n",
"df"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" <th>color</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>a</th>\n",
" <td> 100</td>\n",
" <td> apple</td>\n",
" <td> red</td>\n",
" </tr>\n",
" <tr>\n",
" <th>b</th>\n",
" <td> 150</td>\n",
" <td> orange</td>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>c</th>\n",
" <td> 120</td>\n",
" <td> banana</td>\n",
" <td> yellow</td>\n",
" </tr>\n",
" <tr>\n",
" <th>d</th>\n",
" <td> 140</td>\n",
" <td> NaN</td>\n",
" <td> pink</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 86,
"text": [
" calories fruit color\n",
"a 100 apple red\n",
"b 150 orange orange\n",
"c 120 banana yellow\n",
"d 140 NaN pink"
]
}
],
"prompt_number": 86
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Adding rows, requires a bit more work\n",
"df = df.append({'calories':'100','fruit':'plum','color':'violet'},ignore_index=True)\n",
"df\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" <th>color</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 100</td>\n",
" <td> apple</td>\n",
" <td> red</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 150</td>\n",
" <td> orange</td>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 120</td>\n",
" <td> banana</td>\n",
" <td> yellow</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 140</td>\n",
" <td> NaN</td>\n",
" <td> pink</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 100</td>\n",
" <td> plum</td>\n",
" <td> violet</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 87,
"text": [
" calories fruit color\n",
"0 100 apple red\n",
"1 150 orange orange\n",
"2 120 banana yellow\n",
"3 140 NaN pink\n",
"4 100 plum violet"
]
}
],
"prompt_number": 87
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"C. Delete Data"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df['random_info'] = 'bla'\n",
"df\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" <th>color</th>\n",
" <th>random_info</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 100</td>\n",
" <td> apple</td>\n",
" <td> red</td>\n",
" <td> bla</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 150</td>\n",
" <td> orange</td>\n",
" <td> orange</td>\n",
" <td> bla</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 120</td>\n",
" <td> banana</td>\n",
" <td> yellow</td>\n",
" <td> bla</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 140</td>\n",
" <td> NaN</td>\n",
" <td> pink</td>\n",
" <td> bla</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 100</td>\n",
" <td> plum</td>\n",
" <td> violet</td>\n",
" <td> bla</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 88,
"text": [
" calories fruit color random_info\n",
"0 100 apple red bla\n",
"1 150 orange orange bla\n",
"2 120 banana yellow bla\n",
"3 140 NaN pink bla\n",
"4 100 plum violet bla"
]
}
],
"prompt_number": 88
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"del df['random_info']\n",
"df"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" <th>color</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 100</td>\n",
" <td> apple</td>\n",
" <td> red</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 150</td>\n",
" <td> orange</td>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 120</td>\n",
" <td> banana</td>\n",
" <td> yellow</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 140</td>\n",
" <td> NaN</td>\n",
" <td> pink</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 100</td>\n",
" <td> plum</td>\n",
" <td> violet</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 89,
"text": [
" calories fruit color\n",
"0 100 apple red\n",
"1 150 orange orange\n",
"2 120 banana yellow\n",
"3 140 NaN pink\n",
"4 100 plum violet"
]
}
],
"prompt_number": 89
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"3. Easy to Handle Missing Data"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Create a sample df with missing data\n",
"import numpy as np\n",
"from numpy import nan as NA\n",
"df = DataFrame(np.random.randn(7, 4))\n",
"df.ix[:4, 1] = NA\n",
"df.ix[:2, 2] = NA\n",
"df.ix[:,3] = NA\n",
"df"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" <td> NaN</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" <td> NaN</td>\n",
" <td> 0.823045</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" <td>-1.091542</td>\n",
" <td> 1.117933</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" <td>-0.345692</td>\n",
" <td> 0.584349</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 90,
"text": [
" 0 1 2 3\n",
"0 0.133800 NaN NaN NaN\n",
"1 -1.930645 NaN NaN NaN\n",
"2 0.809217 NaN NaN NaN\n",
"3 -0.785018 NaN -0.498913 NaN\n",
"4 1.159472 NaN 0.823045 NaN\n",
"5 -0.529642 -1.091542 1.117933 NaN\n",
"6 0.574640 -0.345692 0.584349 NaN"
]
}
],
"prompt_number": 90
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# computed statistics ignore NaN\n",
"df.describe()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td> 7.000000</td>\n",
" <td> 2.000000</td>\n",
" <td> 4.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>-0.081168</td>\n",
" <td>-0.718617</td>\n",
" <td> 0.506604</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td> 1.074350</td>\n",
" <td> 0.527396</td>\n",
" <td> 0.704974</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>-1.930645</td>\n",
" <td>-1.091542</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>-0.657330</td>\n",
" <td>-0.905080</td>\n",
" <td> 0.313534</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td> 0.133800</td>\n",
" <td>-0.718617</td>\n",
" <td> 0.703697</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td> 0.691929</td>\n",
" <td>-0.532154</td>\n",
" <td> 0.896767</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td> 1.159472</td>\n",
" <td>-0.345692</td>\n",
" <td> 1.117933</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 91,
"text": [
" 0 1 2 3\n",
"count 7.000000 2.000000 4.000000 0\n",
"mean -0.081168 -0.718617 0.506604 NaN\n",
"std 1.074350 0.527396 0.704974 NaN\n",
"min -1.930645 -1.091542 -0.498913 NaN\n",
"25% -0.657330 -0.905080 0.313534 NaN\n",
"50% 0.133800 -0.718617 0.703697 NaN\n",
"75% 0.691929 -0.532154 0.896767 NaN\n",
"max 1.159472 -0.345692 1.117933 NaN"
]
}
],
"prompt_number": 91
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.dropna()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <tbody>\n",
" <tr>\n",
" <td>Int64Index([], dtype=int64)</td>\n",
" <td>Empty DataFrame</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 92,
"text": [
"Empty DataFrame\n",
"Columns: [0, 1, 2, 3]\n",
"Index: []"
]
}
],
"prompt_number": 92
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.dropna(axis=1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 93,
"text": [
" 0\n",
"0 0.133800\n",
"1 -1.930645\n",
"2 0.809217\n",
"3 -0.785018\n",
"4 1.159472\n",
"5 -0.529642\n",
"6 0.574640"
]
}
],
"prompt_number": 93
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.dropna(how='all',axis=0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" <td> NaN</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" <td> NaN</td>\n",
" <td> 0.823045</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" <td>-1.091542</td>\n",
" <td> 1.117933</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" <td>-0.345692</td>\n",
" <td> 0.584349</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 94,
"text": [
" 0 1 2 3\n",
"0 0.133800 NaN NaN NaN\n",
"1 -1.930645 NaN NaN NaN\n",
"2 0.809217 NaN NaN NaN\n",
"3 -0.785018 NaN -0.498913 NaN\n",
"4 1.159472 NaN 0.823045 NaN\n",
"5 -0.529642 -1.091542 1.117933 NaN\n",
"6 0.574640 -0.345692 0.584349 NaN"
]
}
],
"prompt_number": 94
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.dropna(how='all',axis=1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" <td> NaN</td>\n",
" <td>-0.498913</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" <td> NaN</td>\n",
" <td> 0.823045</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" <td>-1.091542</td>\n",
" <td> 1.117933</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" <td>-0.345692</td>\n",
" <td> 0.584349</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 95,
"text": [
" 0 1 2\n",
"0 0.133800 NaN NaN\n",
"1 -1.930645 NaN NaN\n",
"2 0.809217 NaN NaN\n",
"3 -0.785018 NaN -0.498913\n",
"4 1.159472 NaN 0.823045\n",
"5 -0.529642 -1.091542 1.117933\n",
"6 0.574640 -0.345692 0.584349"
]
}
],
"prompt_number": 95
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.fillna(0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" <td> 0.000000</td>\n",
" <td>-0.498913</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.823045</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" <td>-1.091542</td>\n",
" <td> 1.117933</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" <td>-0.345692</td>\n",
" <td> 0.584349</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 96,
"text": [
" 0 1 2 3\n",
"0 0.133800 0.000000 0.000000 0\n",
"1 -1.930645 0.000000 0.000000 0\n",
"2 0.809217 0.000000 0.000000 0\n",
"3 -0.785018 0.000000 -0.498913 0\n",
"4 1.159472 0.000000 0.823045 0\n",
"5 -0.529642 -1.091542 1.117933 0\n",
"6 0.574640 -0.345692 0.584349 0"
]
}
],
"prompt_number": 96
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"(1/df).fillna(0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 7.473862</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-0.517962</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 1.235762</td>\n",
" <td> 0.000000</td>\n",
" <td> 0.000000</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-1.273856</td>\n",
" <td> 0.000000</td>\n",
" <td>-2.004359</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 0.862462</td>\n",
" <td> 0.000000</td>\n",
" <td> 1.215001</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-1.888068</td>\n",
" <td>-0.916135</td>\n",
" <td> 0.894508</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 1.740220</td>\n",
" <td>-2.892753</td>\n",
" <td> 1.711305</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 97,
"text": [
" 0 1 2 3\n",
"0 7.473862 0.000000 0.000000 0\n",
"1 -0.517962 0.000000 0.000000 0\n",
"2 1.235762 0.000000 0.000000 0\n",
"3 -1.273856 0.000000 -2.004359 0\n",
"4 0.862462 0.000000 1.215001 0\n",
"5 -1.888068 -0.916135 0.894508 0\n",
"6 1.740220 -2.892753 1.711305 0"
]
}
],
"prompt_number": 97
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.fillna(df.mean())"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" <td>-0.718617</td>\n",
" <td> 0.506604</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" <td>-0.718617</td>\n",
" <td> 0.506604</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" <td>-0.718617</td>\n",
" <td> 0.506604</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" <td>-0.718617</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" <td>-0.718617</td>\n",
" <td> 0.823045</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" <td>-1.091542</td>\n",
" <td> 1.117933</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" <td>-0.345692</td>\n",
" <td> 0.584349</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 98,
"text": [
" 0 1 2 3\n",
"0 0.133800 -0.718617 0.506604 NaN\n",
"1 -1.930645 -0.718617 0.506604 NaN\n",
"2 0.809217 -0.718617 0.506604 NaN\n",
"3 -0.785018 -0.718617 -0.498913 NaN\n",
"4 1.159472 -0.718617 0.823045 NaN\n",
"5 -0.529642 -1.091542 1.117933 NaN\n",
"6 0.574640 -0.345692 0.584349 NaN"
]
}
],
"prompt_number": 98
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.fillna(method='bfill')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 0.133800</td>\n",
" <td>-1.091542</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>-1.930645</td>\n",
" <td>-1.091542</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 0.809217</td>\n",
" <td>-1.091542</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>-0.785018</td>\n",
" <td>-1.091542</td>\n",
" <td>-0.498913</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 1.159472</td>\n",
" <td>-1.091542</td>\n",
" <td> 0.823045</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>-0.529642</td>\n",
" <td>-1.091542</td>\n",
" <td> 1.117933</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td> 0.574640</td>\n",
" <td>-0.345692</td>\n",
" <td> 0.584349</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 99,
"text": [
" 0 1 2 3\n",
"0 0.133800 -1.091542 -0.498913 NaN\n",
"1 -1.930645 -1.091542 -0.498913 NaN\n",
"2 0.809217 -1.091542 -0.498913 NaN\n",
"3 -0.785018 -1.091542 -0.498913 NaN\n",
"4 1.159472 -1.091542 0.823045 NaN\n",
"5 -0.529642 -1.091542 1.117933 NaN\n",
"6 0.574640 -0.345692 0.584349 NaN"
]
}
],
"prompt_number": 99
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"4. Easy to Align Data "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# let's merge the user, ratings, and movie dataframes\n",
"movie_data = pd.merge(pd.merge(ratings, users, on ='user_id'), movies,on='movie_id')\n",
"movie_data"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 100,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Int64Index: 1000209 entries, 0 to 1000208\n",
"Data columns:\n",
"user_id 1000209 non-null values\n",
"movie_id 1000209 non-null values\n",
"rating 1000209 non-null values\n",
"timestamp 1000209 non-null values\n",
"gender 1000209 non-null values\n",
"age 1000209 non-null values\n",
"occupation 1000209 non-null values\n",
"zip 1000209 non-null values\n",
"title 1000209 non-null values\n",
"genres 1000209 non-null values\n",
"dtypes: int64(6), object(4)"
]
}
],
"prompt_number": 100
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# suppose that column 'user_id' in ratings called 'user_number'\n",
"ratings = ratings.rename(columns={'user_id':'user_number'})\n",
"ratings\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 101,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Int64Index: 1000209 entries, 0 to 1000208\n",
"Data columns:\n",
"user_number 1000209 non-null values\n",
"movie_id 1000209 non-null values\n",
"rating 1000209 non-null values\n",
"timestamp 1000209 non-null values\n",
"dtypes: int64(4)"
]
}
],
"prompt_number": 101
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"user_ratings = pd.merge(users,ratings,left_on='user_id',right_on='user_number')\n",
"user_ratings"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 102,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Int64Index: 1000209 entries, 0 to 1000208\n",
"Data columns:\n",
"user_id 1000209 non-null values\n",
"gender 1000209 non-null values\n",
"age 1000209 non-null values\n",
"occupation 1000209 non-null values\n",
"zip 1000209 non-null values\n",
"user_number 1000209 non-null values\n",
"movie_id 1000209 non-null values\n",
"rating 1000209 non-null values\n",
"timestamp 1000209 non-null values\n",
"dtypes: int64(7), object(2)"
]
}
],
"prompt_number": 102
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# merge is done in 'outer' mode by default\n",
"df1 = DataFrame({'fruit':['orange','apple','banana','plum','apple'],'color':['orange','red','yellow','violet','green']})\n",
"df2 = DataFrame({'fruit':['orange','apple','banana'],'calories':['100','120','150']}) \n",
"data = pd.merge(df1,df2,on=['fruit']) \n",
"data"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>color</th>\n",
" <th>fruit</th>\n",
" <th>calories</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> orange</td>\n",
" <td> orange</td>\n",
" <td> 100</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> red</td>\n",
" <td> apple</td>\n",
" <td> 120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> green</td>\n",
" <td> apple</td>\n",
" <td> 120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> yellow</td>\n",
" <td> banana</td>\n",
" <td> 150</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 103,
"text": [
" color fruit calories\n",
"0 orange orange 100\n",
"1 red apple 120\n",
"2 green apple 120\n",
"3 yellow banana 150"
]
}
],
"prompt_number": 103
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"data = pd.merge(df1,df2,on=['fruit'],how='outer')\n",
"data"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>color</th>\n",
" <th>fruit</th>\n",
" <th>calories</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> orange</td>\n",
" <td> orange</td>\n",
" <td> 100</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> red</td>\n",
" <td> apple</td>\n",
" <td> 120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> green</td>\n",
" <td> apple</td>\n",
" <td> 120</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> yellow</td>\n",
" <td> banana</td>\n",
" <td> 150</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> violet</td>\n",
" <td> plum</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 104,
"text": [
" color fruit calories\n",
"0 orange orange 100\n",
"1 red apple 120\n",
"2 green apple 120\n",
"3 yellow banana 150\n",
"4 violet plum NaN"
]
}
],
"prompt_number": 104
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Merging on an index\n",
"# First let's make the fruit column in df1 an index\n",
"df1 = df1.set_index(['fruit'])\n",
"df1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>color</th>\n",
" </tr>\n",
" <tr>\n",
" <th>fruit</th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>orange</th>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>apple</th>\n",
" <td> red</td>\n",
" </tr>\n",
" <tr>\n",
" <th>banana</th>\n",
" <td> yellow</td>\n",
" </tr>\n",
" <tr>\n",
" <th>plum</th>\n",
" <td> violet</td>\n",
" </tr>\n",
" <tr>\n",
" <th>apple</th>\n",
" <td> green</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 105,
"text": [
" color\n",
"fruit \n",
"orange orange\n",
"apple red\n",
"banana yellow\n",
"plum violet\n",
"apple green"
]
}
],
"prompt_number": 105
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# let's merge on fruit. \n",
"# fruit is an index in df1 and a column in df2 \n",
"data = pd.merge(df1,df2,left_index=True,right_on='fruit')\n",
"data"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>color</th>\n",
" <th>calories</th>\n",
" <th>fruit</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> orange</td>\n",
" <td> 100</td>\n",
" <td> orange</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> red</td>\n",
" <td> 120</td>\n",
" <td> apple</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> green</td>\n",
" <td> 120</td>\n",
" <td> apple</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> yellow</td>\n",
" <td> 150</td>\n",
" <td> banana</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 106,
"text": [
" color calories fruit\n",
"0 orange 100 orange\n",
"1 red 120 apple\n",
"1 green 120 apple\n",
"2 yellow 150 banana"
]
}
],
"prompt_number": 106
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# How about 'merging' or concatenating multiple DataFrames\n",
"# Example using baby name dataset\n",
"years = xrange(1880, 2011)\n",
"pieces = []\n",
"columns = ['name', 'sex', 'births']\n",
"for year in years:\n",
" path = '/Users/gchoueiter/Documents/Classes/panda/pydata-book/ch02/names/yob%d.txt' % year\n",
" frame = pd.read_csv(path, names=columns)\n",
" frame['year'] = year \n",
" pieces.append(frame)\n",
" \n",
"names = pd.concat(pieces,ignore_index=True)\n",
"names"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 107,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Int64Index: 1690784 entries, 0 to 1690783\n",
"Data columns:\n",
"name 1690784 non-null values\n",
"sex 1690784 non-null values\n",
"births 1690784 non-null values\n",
"year 1690784 non-null values\n",
"dtypes: int64(2), object(2)"
]
}
],
"prompt_number": 107
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"5. Easy to Group Data "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# A very common way to group data\n",
"# let's go back to the movie example\n",
"mean_ratings = movie_data.groupby(['gender','title'])['rating'].mean()\n",
"mean_ratings[:5]\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 108,
"text": [
"gender title \n",
"F $1,000,000 Duck (1971) 3.375000\n",
" 'Night Mother (1986) 3.388889\n",
" 'Til There Was You (1997) 2.675676\n",
" 'burbs, The (1989) 2.793478\n",
" ...And Justice for All (1979) 3.828571\n",
"Name: rating"
]
}
],
"prompt_number": 108
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# another way to group/aggregate data\n",
"mean_ratings = movie_data.pivot_table('rating',rows='title',cols='gender',aggfunc='mean')\n",
"mean_ratings[:5] \n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>gender</th>\n",
" <th>F</th>\n",
" <th>M</th>\n",
" </tr>\n",
" <tr>\n",
" <th>title</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>$1,000,000 Duck (1971)</th>\n",
" <td> 3.375000</td>\n",
" <td> 2.761905</td>\n",
" </tr>\n",
" <tr>\n",
" <th>'Night Mother (1986)</th>\n",
" <td> 3.388889</td>\n",
" <td> 3.352941</td>\n",
" </tr>\n",
" <tr>\n",
" <th>'Til There Was You (1997)</th>\n",
" <td> 2.675676</td>\n",
" <td> 2.733333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>'burbs, The (1989)</th>\n",
" <td> 2.793478</td>\n",
" <td> 2.962085</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...And Justice for All (1979)</th>\n",
" <td> 3.828571</td>\n",
" <td> 3.689024</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 109,
"text": [
"gender F M\n",
"title \n",
"$1,000,000 Duck (1971) 3.375000 2.761905\n",
"'Night Mother (1986) 3.388889 3.352941\n",
"'Til There Was You (1997) 2.675676 2.733333\n",
"'burbs, The (1989) 2.793478 2.962085\n",
"...And Justice for All (1979) 3.828571 3.689024"
]
}
],
"prompt_number": 109
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"mean_ratings.hist()\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 110,
"text": [
"array([[Axes(0.125,0.125;0.336957x0.775),\n",
" Axes(0.563043,0.125;0.336957x0.775)]], dtype=object)"
]
},
{
"output_type": "display_data",
"png": "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\n"
}
],
"prompt_number": 110
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"mean_ratings.describe()\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>gender</th>\n",
" <th>F</th>\n",
" <th>M</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td> 3481.000000</td>\n",
" <td> 3671.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td> 3.293716</td>\n",
" <td> 3.217015</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td> 0.714311</td>\n",
" <td> 0.686186</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td> 1.000000</td>\n",
" <td> 1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td> 2.888889</td>\n",
" <td> 2.794190</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td> 3.381356</td>\n",
" <td> 3.307692</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td> 3.824176</td>\n",
" <td> 3.721798</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td> 5.000000</td>\n",
" <td> 5.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 111,
"text": [
"gender F M\n",
"count 3481.000000 3671.000000\n",
"mean 3.293716 3.217015\n",
"std 0.714311 0.686186\n",
"min 1.000000 1.000000\n",
"25% 2.888889 2.794190\n",
"50% 3.381356 3.307692\n",
"75% 3.824176 3.721798\n",
"max 5.000000 5.000000"
]
}
],
"prompt_number": 111
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# groupby + apply = data transformation\n",
"\n",
"# function applied to a group\n",
"def zscore(group):\n",
" return (group - group.mean()) / group.std()\n",
"\n",
"# applied to a string\n",
"def movie_title_length(title):\n",
" return len(title.split(' '))\n",
"\n",
"# data transformation examples with apply \n",
"movie_data['rating_zscore_by_gender'] = movie_data.groupby(['gender','title'])['rating'].apply(zscore)\n",
"\n",
"# data transformation examples with map (applies on Series)\n",
"movie_data['rating_mean_by_gender'] = movie_data.groupby(['gender','title'])['rating'].map(mean)\n",
"movie_data['title_length'] = movie_data['title'].map(movie_title_length)\n",
"\n",
"movie_data[:5]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>user_id</th>\n",
" <th>movie_id</th>\n",
" <th>rating</th>\n",
" <th>timestamp</th>\n",
" <th>gender</th>\n",
" <th>age</th>\n",
" <th>occupation</th>\n",
" <th>zip</th>\n",
" <th>title</th>\n",
" <th>genres</th>\n",
" <th>rating_zscore_by_gender</th>\n",
" <th>rating_mean_by_gender</th>\n",
" <th>title_length</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td> 1</td>\n",
" <td> 1193</td>\n",
" <td> 5</td>\n",
" <td> 978300760</td>\n",
" <td> F</td>\n",
" <td> 1</td>\n",
" <td> 10</td>\n",
" <td> 48067</td>\n",
" <td> One Flew Over the Cuckoo's Nest (1975)</td>\n",
" <td> Drama</td>\n",
" <td> 0.814585</td>\n",
" <td> 5</td>\n",
" <td> 7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td> 2</td>\n",
" <td> 1193</td>\n",
" <td> 5</td>\n",
" <td> 978298413</td>\n",
" <td> M</td>\n",
" <td> 56</td>\n",
" <td> 16</td>\n",
" <td> 70072</td>\n",
" <td> One Flew Over the Cuckoo's Nest (1975)</td>\n",
" <td> Drama</td>\n",
" <td> 0.757889</td>\n",
" <td> 5</td>\n",
" <td> 7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td> 12</td>\n",
" <td> 1193</td>\n",
" <td> 4</td>\n",
" <td> 978220179</td>\n",
" <td> M</td>\n",
" <td> 25</td>\n",
" <td> 12</td>\n",
" <td> 32793</td>\n",
" <td> One Flew Over the Cuckoo's Nest (1975)</td>\n",
" <td> Drama</td>\n",
" <td>-0.545273</td>\n",
" <td> 4</td>\n",
" <td> 7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td> 15</td>\n",
" <td> 1193</td>\n",
" <td> 4</td>\n",
" <td> 978199279</td>\n",
" <td> M</td>\n",
" <td> 25</td>\n",
" <td> 7</td>\n",
" <td> 22903</td>\n",
" <td> One Flew Over the Cuckoo's Nest (1975)</td>\n",
" <td> Drama</td>\n",
" <td>-0.545273</td>\n",
" <td> 4</td>\n",
" <td> 7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td> 17</td>\n",
" <td> 1193</td>\n",
" <td> 5</td>\n",
" <td> 978158471</td>\n",
" <td> M</td>\n",
" <td> 50</td>\n",
" <td> 1</td>\n",
" <td> 95350</td>\n",
" <td> One Flew Over the Cuckoo's Nest (1975)</td>\n",
" <td> Drama</td>\n",
" <td> 0.757889</td>\n",
" <td> 5</td>\n",
" <td> 7</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 114,
"text": [
" user_id movie_id rating timestamp gender age occupation zip \\\n",
"0 1 1193 5 978300760 F 1 10 48067 \n",
"1 2 1193 5 978298413 M 56 16 70072 \n",
"2 12 1193 4 978220179 M 25 12 32793 \n",
"3 15 1193 4 978199279 M 25 7 22903 \n",
"4 17 1193 5 978158471 M 50 1 95350 \n",
"\n",
" title genres rating_zscore_by_gender \\\n",
"0 One Flew Over the Cuckoo's Nest (1975) Drama 0.814585 \n",
"1 One Flew Over the Cuckoo's Nest (1975) Drama 0.757889 \n",
"2 One Flew Over the Cuckoo's Nest (1975) Drama -0.545273 \n",
"3 One Flew Over the Cuckoo's Nest (1975) Drama -0.545273 \n",
"4 One Flew Over the Cuckoo's Nest (1975) Drama 0.757889 \n",
"\n",
" rating_mean_by_gender title_length \n",
"0 5 7 \n",
"1 5 7 \n",
"2 4 7 \n",
"3 4 7 \n",
"4 5 7 "
]
}
],
"prompt_number": 114
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.scatter(movie_data['rating_mean_by_gender'],movie_data['title_length'])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 113,
"text": [
"<matplotlib.collections.PathCollection at 0xf127750>"
]
},
{
"output_type": "display_data",
"png": "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\n"
}
],
"prompt_number": 113
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment