{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "

Table of Contents

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Drawing\"" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np # necessity as pandas is built on np\n", "from IPython.display import Image # to display images " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Pandas library is built on NumPy and provides easy-to-use data structures and data analysis tools for the Python programming language. \n", " \n", "Refer to these cheatsheets: \n", "https://s3.amazonaws.com/assets.datacamp.com/blog_assets/PandasPythonForDataScience+(1).pdf\n", "https://s3.amazonaws.com/assets.datacamp.com/blog_assets/Python_Pandas_Cheat_Sheet_2.pdf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Input/Output\n", "Different types of data can be loaded in pandas dataframe. Pandas dataframe is like looks spreadsheet table (just a rough analogy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* **Most common input types**\n", " * `pd.read_csv`\n", " * `pd.read_excel/ pd.ExcelFile`\n", " * `pd.read_feather` (feather format is used to reduce memory load in df as data is saved in binary form)\n", " * `pd.read_json`\n", " * `pd.read_html`\n", " * `pd.read_pickle` (can also infer if pickled object is zipped using infer=)\n", " \n", "* **Output types have format `to_xxx` similar to input formats**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas data structures" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "** Pandas data strctures include `series` and `dataframe` **" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Series**: A one-dimensional labeled array a capable of holding any data type " ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "execution_count": 18, "metadata": { "image/png": { "width": 500 } }, "output_type": "execute_result" } ], "source": [ "Image('../images/series.png', width=500) # not pandas, just showing example series" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "# index will set the index for further reference\n", "# data can be passed as list\n", "s = pd.Series([3, -5, 7, 4], index=['a', 'b', 'c', 'd']) " ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 3\n", "b -5\n", "c 7\n", "d 4\n", "dtype: int64" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Can be indexed using both index name or number.** \n", "number: --> filter indexes after value of number \n", ":number --> filter indexes before value of number " ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b -5\n", "c 7\n", "d 4\n", "dtype: int64" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s[1:]" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s['a'] " ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 3\n", "b -5\n", "c 7\n", "dtype: int64" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s[:'c']" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['a', 'b', 'c', 'd'], dtype='object')" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.index" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "a 3\n", "b -1\n", "c 12\n", "dtype: int64" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# series using dictionary\n", "\n", "s2 = pd.Series({'a':3, 'b': -1, 'c': 12}); s2" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-1" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2['b']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Dataframe**: A two-dimensional labeled data structure with columns of potentially different types. It is similar to excel table. \n", "\n", "Can make data frame using dictionary, list of list" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "scrolled": true }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "execution_count": 25, "metadata": { "image/png": { "width": 500 } }, "output_type": "execute_result" } ], "source": [ "Image('../images/df.png', width=500) " ] }, { "cell_type": "code", "execution_count": 288, "metadata": {}, "outputs": [], "source": [ "data = {'Country': ['Belgium', 'India', 'Brazil'],\n", " 'Capital': ['Brussels', 'New Delhi', 'Brasília'],\n", " 'Population': [11190846, 1303171035, 207847528]}" ] }, { "cell_type": "code", "execution_count": 289, "metadata": {}, "outputs": [], "source": [ "df_sample = pd.DataFrame(data,\n", " columns=['Country', 'Capital', 'Population'])" ] }, { "cell_type": "code", "execution_count": 290, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CountryCapitalPopulation
0BelgiumBrussels11190846
1IndiaNew Delhi1303171035
2BrazilBrasília207847528
\n", "
" ], "text/plain": [ " Country Capital Population\n", "0 Belgium Brussels 11190846\n", "1 India New Delhi 1303171035\n", "2 Brazil Brasília 207847528" ] }, "execution_count": 290, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_sample" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Common dataframe functionality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using famous `titanic data` for analysis and exploration. \n", "https://www.kaggle.com/c/titanic/data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* **Common things to do when we get data in a dataframe (examples shown below):** \n", " * see dataframe shape (number of rows, number of columns) using `df.shape`\n", " * see top 5 rows using `pd.head()`\n", " * check datatype of each column using `pd.dtypes`\n", " * check column names using `pd.columns`\n", " * count unique values of each column to see cardinality levels using `pd.nunique()`\n", " * number of non null in each column, memory usage of df, datatype (especially for large df) using `pd.info()`\n", " \n", " " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv('../data/train.csv') # read csv file" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(891, 12)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.shape" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "0 1 0 3 \n", "1 2 1 1 \n", "2 3 1 3 \n", "3 4 1 1 \n", "4 5 0 3 \n", "\n", " Name Sex Age SibSp \\\n", "0 Braund, Mr. Owen Harris male 22.0 1 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "2 Heikkinen, Miss. Laina female 26.0 0 \n", "3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n", "4 Allen, Mr. William Henry male 35.0 0 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "0 0 A/5 21171 7.2500 NaN S \n", "1 0 PC 17599 71.2833 C85 C \n", "2 0 STON/O2. 3101282 7.9250 NaN S \n", "3 0 113803 53.1000 C123 S \n", "4 0 373450 8.0500 NaN S " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head() # see top 5 rows of data" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PassengerId int64\n", "Survived int64\n", "Pclass int64\n", "Name object\n", "Sex object\n", "Age float64\n", "SibSp int64\n", "Parch int64\n", "Ticket object\n", "Fare float64\n", "Cabin object\n", "Embarked object\n", "dtype: object" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.dtypes # see datatype of each variable" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',\n", " 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],\n", " dtype='object')" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.columns # column names" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PassengerId 891\n", "Survived 2\n", "Pclass 3\n", "Name 891\n", "Sex 2\n", "Age 88\n", "SibSp 7\n", "Parch 7\n", "Ticket 681\n", "Fare 248\n", "Cabin 147\n", "Embarked 3\n", "dtype: int64" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.nunique() # unique value for each variable" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 891 entries, 0 to 890\n", "Data columns (total 12 columns):\n", "PassengerId 891 non-null int64\n", "Survived 891 non-null int64\n", "Pclass 891 non-null int64\n", "Name 891 non-null object\n", "Sex 891 non-null object\n", "Age 714 non-null float64\n", "SibSp 891 non-null int64\n", "Parch 891 non-null int64\n", "Ticket 891 non-null object\n", "Fare 891 non-null float64\n", "Cabin 204 non-null object\n", "Embarked 889 non-null object\n", "dtypes: float64(2), int64(5), object(5)\n", "memory usage: 83.6+ KB\n" ] } ], "source": [ "df.info() # not null part is very useful to see how many nulls are there in data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Advanced Indexing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `iloc` \n", "Select based on integer location (**that's why i**). Can select single or multiple" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'male'" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[0, 4] # 0 row, 4 column" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PclassNameSexAge
11Cumings, Mrs. John Bradley (Florence Briggs Th...female38.0
23Heikkinen, Miss. Lainafemale26.0
31Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.0
\n", "
" ], "text/plain": [ " Pclass Name Sex Age\n", "1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0\n", "2 3 Heikkinen, Miss. Laina female 26.0\n", "3 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[1:4, 2:6] # indexes are maintained. Can reset_index() to start index from 0 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `loc`\n", "Select based on label name of column (can select single or multiple)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameSexAge
1Cumings, Mrs. John Bradley (Florence Briggs Th...female38.0
2Heikkinen, Miss. Lainafemale26.0
\n", "
" ], "text/plain": [ " Name Sex Age\n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0\n", "2 Heikkinen, Miss. Laina female 26.0" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[1:2,'Name':\"Age\"] # here row indexes are numbers but column indexes are name of columns " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Name Heikkinen, Miss. Laina\n", "Age 26\n", "Name: 2, dtype: object" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[2,['Name',\"Age\"]] # here row indexes are numbers. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `ix`\n", "ix has been deprecated in latest pandas library. It was used to select by label or position. But we can always use `loc` to select with labels and `iloc` to select with integers/position" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `Boolean indexing`\n", "Returns rows where the stated condition returns true\n", "\n", "* or -> condition 1 `|` condition 2 (`or` also works but throws ambiguity error for multiple conditions)\n", "* and -> condition 1 `&` condition 2 (`and` also works but throws ambiguity error for multiple conditions\n", "* not -> `~` (not condition)\n", "* equal -> `==` Satisfying condition \n", "* `any()` -> columns/rows with any value matching condition\n", "* `all()` > columns/rows with all values matching some condition" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "1 2 1 1 \n", "2 3 1 3 \n", "3 4 1 1 \n", "\n", " Name Sex Age SibSp \\\n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "2 Heikkinen, Miss. Laina female 26.0 0 \n", "3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "1 0 PC 17599 71.2833 C85 C \n", "2 0 STON/O2. 3101282 7.9250 NaN S \n", "3 0 113803 53.1000 C123 S " ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# select rows with either sex as female or Pclass as 1\n", "df[(df.Sex == 'female') | (df.iloc[:,2] == 1) ].iloc[:3] # () are important" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameSexTicketCabinEmbarked
0Braund, Mr. Owen HarrismaleA/5 21171NaNS
1Cumings, Mrs. John Bradley (Florence Briggs Th...femalePC 17599C85C
2Heikkinen, Miss. LainafemaleSTON/O2. 3101282NaNS
\n", "
" ], "text/plain": [ " Name Sex \\\n", "0 Braund, Mr. Owen Harris male \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female \n", "2 Heikkinen, Miss. Laina female \n", "\n", " Ticket Cabin Embarked \n", "0 A/5 21171 NaN S \n", "1 PC 17599 C85 C \n", "2 STON/O2. 3101282 NaN S " ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# first 3 rows of gives all columns which have all string values or all int > 1 values\n", "df.loc[:,(df > 1).all()][:3] " ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexSibSpParchTicketFare
0103Braund, Mr. Owen Harrismale10A/5 211717.2500
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female10PC 1759971.2833
2313Heikkinen, Miss. Lainafemale00STON/O2. 31012827.9250
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "0 1 0 3 \n", "1 2 1 1 \n", "2 3 1 3 \n", "\n", " Name Sex SibSp Parch \\\n", "0 Braund, Mr. Owen Harris male 1 0 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 1 0 \n", "2 Heikkinen, Miss. Laina female 0 0 \n", "\n", " Ticket Fare \n", "0 A/5 21171 7.2500 \n", "1 PC 17599 71.2833 \n", "2 STON/O2. 3101282 7.9250 " ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# first 3 rows of all columns which have all not null values\n", "df.loc[:,(df.notnull().all() )][:3]" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AgeCabinEmbarked
022.0NaNS
138.0C85C
226.0NaNS
\n", "
" ], "text/plain": [ " Age Cabin Embarked\n", "0 22.0 NaN S\n", "1 38.0 C85 C\n", "2 26.0 NaN S" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# first 3 rows of all columns which have atleast 1 null value\n", "df.loc[:, df.isnull().any()][:3]" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(94, 12)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[(df.iloc[:,2] == 1) & (df.Sex == 'female')].shape" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.3075196408529742" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# fraction of males with Age > 25, df.shape[0] -> number of rows \n", "\n", "sum((df.Age > 25) & (df.Sex == 'male'))/df.shape[0] " ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "223" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# number of people who survived and were not in class 3\n", "\n", "sum((df.Survived != 0) & (~(df.Pclass == 3)) ) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `querying`\n", "Query columns (filter rows) of dataframe with boolean expression (Filter based on condition)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
8913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female27.00234774211.1333NaNS
91012Nasser, Mrs. Nicholas (Adele Achem)female14.01023773630.0708NaNC
111211Bonnell, Miss. Elizabethfemale58.00011378326.5500C103S
121303Saundercock, Mr. William Henrymale20.000A/5. 21518.0500NaNS
131403Andersson, Mr. Anders Johanmale39.01534708231.2750NaNS
151612Hewlett, Mrs. (Mary D Kingcome)female55.00024870616.0000NaNS
181903Vander Planke, Mrs. Julius (Emelia Maria Vande...female31.01034576318.0000NaNS
202102Fynney, Mr. Joseph Jmale35.00023986526.0000NaNS
212212Beesley, Mr. Lawrencemale34.00024869813.0000D56S
232411Sloper, Mr. William Thompsonmale28.00011378835.5000A6S
252613Asplund, Mrs. Carl Oscar (Selma Augusta Emilia...female38.01534707731.3875NaNS
303101Uruchurtu, Don. Manuel Emale40.000PC 1760127.7208NaNC
333402Wheadon, Mr. Edward Hmale66.000C.A. 2457910.5000NaNS
353601Holverson, Mr. Alexander Oskarmale42.01011378952.0000NaNS
545501Ostby, Mr. Engelhart Corneliusmale65.00111350961.9792B30C
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "0 1 0 3 \n", "1 2 1 1 \n", "2 3 1 3 \n", "3 4 1 1 \n", "4 5 0 3 \n", "6 7 0 1 \n", "8 9 1 3 \n", "9 10 1 2 \n", "11 12 1 1 \n", "12 13 0 3 \n", "13 14 0 3 \n", "15 16 1 2 \n", "18 19 0 3 \n", "20 21 0 2 \n", "21 22 1 2 \n", "23 24 1 1 \n", "25 26 1 3 \n", "30 31 0 1 \n", "33 34 0 2 \n", "35 36 0 1 \n", "54 55 0 1 \n", "\n", " Name Sex Age SibSp \\\n", "0 Braund, Mr. Owen Harris male 22.0 1 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "2 Heikkinen, Miss. Laina female 26.0 0 \n", "3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n", "4 Allen, Mr. William Henry male 35.0 0 \n", "6 McCarthy, Mr. Timothy J male 54.0 0 \n", "8 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female 27.0 0 \n", "9 Nasser, Mrs. Nicholas (Adele Achem) female 14.0 1 \n", "11 Bonnell, Miss. Elizabeth female 58.0 0 \n", "12 Saundercock, Mr. William Henry male 20.0 0 \n", "13 Andersson, Mr. Anders Johan male 39.0 1 \n", "15 Hewlett, Mrs. (Mary D Kingcome) female 55.0 0 \n", "18 Vander Planke, Mrs. Julius (Emelia Maria Vande... female 31.0 1 \n", "20 Fynney, Mr. Joseph J male 35.0 0 \n", "21 Beesley, Mr. Lawrence male 34.0 0 \n", "23 Sloper, Mr. William Thompson male 28.0 0 \n", "25 Asplund, Mrs. Carl Oscar (Selma Augusta Emilia... female 38.0 1 \n", "30 Uruchurtu, Don. Manuel E male 40.0 0 \n", "33 Wheadon, Mr. Edward H male 66.0 0 \n", "35 Holverson, Mr. Alexander Oskar male 42.0 1 \n", "54 Ostby, Mr. Engelhart Cornelius male 65.0 0 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "0 0 A/5 21171 7.2500 NaN S \n", "1 0 PC 17599 71.2833 C85 C \n", "2 0 STON/O2. 3101282 7.9250 NaN S \n", "3 0 113803 53.1000 C123 S \n", "4 0 373450 8.0500 NaN S \n", "6 0 17463 51.8625 E46 S \n", "8 2 347742 11.1333 NaN S \n", "9 0 237736 30.0708 NaN C \n", "11 0 113783 26.5500 C103 S \n", "12 0 A/5. 2151 8.0500 NaN S \n", "13 5 347082 31.2750 NaN S \n", "15 0 248706 16.0000 NaN S \n", "18 0 345763 18.0000 NaN S \n", "20 0 239865 26.0000 NaN S \n", "21 0 248698 13.0000 D56 S \n", "23 0 113788 35.5000 A6 S \n", "25 5 347077 31.3875 NaN S \n", "30 0 PC 17601 27.7208 NaN C \n", "33 0 C.A. 24579 10.5000 NaN S \n", "35 0 113789 52.0000 NaN S \n", "54 1 113509 61.9792 B30 C " ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# filter all rows which have Age > Passenger ID\n", "df.query('Age > PassengerId')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`filter` \n", "\n", "Filter dataframe on column names or row names (labels) by regrex or just item names" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AgeSex
022.0male
138.0female
\n", "
" ], "text/plain": [ " Age Sex\n", "0 22.0 male\n", "1 38.0 female" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# filter only sex and age columns (first 2 rows)\n", "\n", "df.filter(items=['Age', 'Sex'])[:2]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
5603Moran, Mr. JamesmaleNaN003308778.4583NaNQ
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass Name Sex Age SibSp \\\n", "0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 \n", "5 6 0 3 Moran, Mr. James male NaN 0 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "0 0 A/5 21171 7.2500 NaN S \n", "5 0 330877 8.4583 NaN Q " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# filter only 0 and 5 row index\n", "\n", "df.filter(items=[0,5], axis=0)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
SurvivedEmbarked
00S
11C
\n", "
" ], "text/plain": [ " Survived Embarked\n", "0 0 S\n", "1 1 C" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# first 2 rows of column names ending with \"ed\" (think of past tense)\n", "\n", "df.filter(like = 'ed', axis=1)[:2]" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Series([], Name: Name, dtype: object)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Can use same thing as above using regex also\n", "\n", "df.filter(regex='ed$', axis=1)[:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `isin` \n", "\n", "Filter rows of column based on list of multiple values" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
111211Bonnell, Miss. Elizabethfemale58.00011378326.5500C103S
232411Sloper, Mr. William Thompsonmale28.00011378835.5000A6S
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "1 2 1 1 \n", "3 4 1 1 \n", "6 7 0 1 \n", "11 12 1 1 \n", "23 24 1 1 \n", "\n", " Name Sex Age SibSp \\\n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n", "6 McCarthy, Mr. Timothy J male 54.0 0 \n", "11 Bonnell, Miss. Elizabeth female 58.0 0 \n", "23 Sloper, Mr. William Thompson male 28.0 0 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "1 0 PC 17599 71.2833 C85 C \n", "3 0 113803 53.1000 C123 S \n", "6 0 17463 51.8625 E46 S \n", "11 0 113783 26.5500 C103 S \n", "23 0 113788 35.5000 A6 S " ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[df.Pclass.isin([0,1])].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setting/ Resetting Index\n", "Setting and resetting index are important when we merge/groupby 2 dataframe and want to do further analysis on new dataframe. A dataframe with repeated indexes can cause problems in filtering. Apart from this we cvan set a column into index which makes merging much faster" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `set_index()`\n", "Set any column you want as index of df" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchFareCabinEmbarked
Ticket
A/5 21171103Braund, Mr. Owen Harrismale22.0107.2500NaNS
PC 17599211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.01071.2833C85C
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "Ticket \n", "A/5 21171 1 0 3 \n", "PC 17599 2 1 1 \n", "\n", " Name Sex Age \\\n", "Ticket \n", "A/5 21171 Braund, Mr. Owen Harris male 22.0 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 \n", "\n", " SibSp Parch Fare Cabin Embarked \n", "Ticket \n", "A/5 21171 1 0 7.2500 NaN S \n", "PC 17599 1 0 71.2833 C85 C " ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# setting \n", "df.set_index('Ticket')[:2]" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassSexAgeSibSpParchFareCabinEmbarked
TicketName
A/5 21171Braund, Mr. Owen Harris103male22.0107.2500NaNS
PC 17599Cumings, Mrs. John Bradley (Florence Briggs Thayer)211female38.01071.2833C85C
\n", "
" ], "text/plain": [ " PassengerId \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 1 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 2 \n", "\n", " Survived \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 0 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 1 \n", "\n", " Pclass Sex \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 3 male \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 1 female \n", "\n", " Age SibSp \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 22.0 1 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 38.0 1 \n", "\n", " Parch Fare \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 0 7.2500 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 0 71.2833 \n", "\n", " Cabin Embarked \n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris NaN S \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... C85 C " ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can set multiple columns as index also. Just pass them in list\n", "# Setting Ticket and Name as index\n", "\n", "df.set_index(['Ticket', 'Name'])[:2]" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('A/5 21171', 'Braund, Mr. Owen Harris')" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can see what are values of index. \n", "# checking index of 1st row\n", "\n", "df.set_index(['Ticket', 'Name']).index[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `reset_index()`\n", "Can reset index back to 0....nrows-1" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [], "source": [ "df_index = df.set_index(['Ticket', 'Name'])" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassSexAgeSibSpParchFareCabinEmbarked
TicketName
A/5 21171Braund, Mr. Owen Harris103male22.0107.2500NaNS
PC 17599Cumings, Mrs. John Bradley (Florence Briggs Thayer)211female38.01071.2833C85C
\n", "
" ], "text/plain": [ " PassengerId \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 1 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 2 \n", "\n", " Survived \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 0 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 1 \n", "\n", " Pclass Sex \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 3 male \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 1 female \n", "\n", " Age SibSp \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 22.0 1 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 38.0 1 \n", "\n", " Parch Fare \\\n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris 0 7.2500 \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... 0 71.2833 \n", "\n", " Cabin Embarked \n", "Ticket Name \n", "A/5 21171 Braund, Mr. Owen Harris NaN S \n", "PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Tha... C85 C " ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_index[:2]" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TicketNamePassengerIdSurvivedPclassSexAgeSibSpParchFareCabinEmbarked
0A/5 21171Braund, Mr. Owen Harris103male22.0107.2500NaNS
1PC 17599Cumings, Mrs. John Bradley (Florence Briggs Th...211female38.01071.2833C85C
\n", "
" ], "text/plain": [ " Ticket Name PassengerId \\\n", "0 A/5 21171 Braund, Mr. Owen Harris 1 \n", "1 PC 17599 Cumings, Mrs. John Bradley (Florence Briggs Th... 2 \n", "\n", " Survived Pclass Sex Age SibSp Parch Fare Cabin Embarked \n", "0 0 3 male 22.0 1 0 7.2500 NaN S \n", "1 1 1 female 38.0 1 0 71.2833 C85 C " ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_index.reset_index()[:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In above case, index is back to 0,1..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `rename()` \n", "Renaming column names or row indexes of dataframe. Default is index" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassWhats_nameSexAgeSibSpParchTicketPriceCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "0 1 0 3 \n", "1 2 1 1 \n", "\n", " Whats_name Sex Age SibSp \\\n", "0 Braund, Mr. Owen Harris male 22.0 1 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "\n", " Parch Ticket Price Cabin Embarked \n", "0 0 A/5 21171 7.2500 NaN S \n", "1 0 PC 17599 71.2833 C85 C " ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.rename(columns={'Name': 'Whats_name', 'Fare':'Price'})[:2]" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
passengeridsurvivedpclassnamesexagesibspparchticketfarecabinembarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
\n", "
" ], "text/plain": [ " passengerid survived pclass \\\n", "0 1 0 3 \n", "1 2 1 1 \n", "\n", " name sex age sibsp \\\n", "0 Braund, Mr. Owen Harris male 22.0 1 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n", "\n", " parch ticket fare cabin embarked \n", "0 0 A/5 21171 7.2500 NaN S \n", "1 0 PC 17599 71.2833 C85 C " ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can use some mapper function also. default axis='index' (0)\n", "\n", "df.rename(mapper=str.lower, axis='columns')[:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Duplicated data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `unique()`\n", "Number of unique values in a column of df (Use nunique() for count of unique in each column)" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['male', 'female'], dtype=object)" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.Sex.unique()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `duplicated()`\n", "Check duplicated in column. Returns True/False" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(df.PassengerId.duplicated()) # there are no duplicate passegerid. good thing to check" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can check duplicates in index also.\n", "# useful if doubtful about duplicates in index doing bad things \n", "\n", "sum(df.index.duplicated())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `drop_duplicates`\n", "Drop rows which have duplicates" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
SexEmbarked
0maleS
1femaleC
2femaleS
5maleQ
22femaleQ
26maleC
61femaleNaN
\n", "
" ], "text/plain": [ " Sex Embarked\n", "0 male S\n", "1 female C\n", "2 female S\n", "5 male Q\n", "22 female Q\n", "26 male C\n", "61 female NaN" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can help in getting unique combination of multiple columns\n", "# unique() dosn't work in this case\n", "df.loc[:,['Sex', 'Embarked']].drop_duplicates()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Grouping data\n", "Group by some column/columns, then we can aggregate to get mean, count, sum or custom function based on the group" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `groupby`" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameAgeSibSpParchTicketFareCabinEmbarked
Sex
female31431431431426131431431431497312
male577577577577453577577577577107577
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass Name Age SibSp Parch Ticket Fare \\\n", "Sex \n", "female 314 314 314 314 261 314 314 314 314 \n", "male 577 577 577 577 453 577 577 577 577 \n", "\n", " Cabin Embarked \n", "Sex \n", "female 97 312 \n", "male 107 577 " ] }, "execution_count": 123, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# group by sex then count. \n", "# returns count in each column. difference in some cases because of nulls in those columns\n", "# can do iloc[:,0] to only get first column \n", "\n", "df.groupby(by = ['Sex']).count()" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sex Survived\n", "female 0 25.046875\n", " 1 28.847716\n", "male 0 31.618056\n", " 1 27.276022\n", "Name: Age, dtype: float64" ] }, "execution_count": 125, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can use multiple conditions\n", "# group by sex and survived -> mean of age\n", "\n", "df.groupby(by = ['Sex', 'Survived']).mean().loc[:,'Age']" ] }, { "cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
FareAge
SexPclass
female1106.12579834.611765
221.97012128.722973
316.11881021.750000
male167.22612741.281386
219.74178230.740707
312.66163326.507589
\n", "
" ], "text/plain": [ " Fare Age\n", "Sex Pclass \n", "female 1 106.125798 34.611765\n", " 2 21.970121 28.722973\n", " 3 16.118810 21.750000\n", "male 1 67.226127 41.281386\n", " 2 19.741782 30.740707\n", " 3 12.661633 26.507589" ] }, "execution_count": 145, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# can group by indexes also by using levels= \n", "# useful when we have multindexes\n", "# can use agg function with lambda func\n", "\n", "df_index = df.set_index(['Sex', 'Pclass'])\n", "df_index.groupby(level=[0,1]).agg({'Fare': lambda x: sum(x)/len(x), # this is also just mean actually\n", " 'Age' : np.mean})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interesting! Ticket price of 1st class female is approximately double of 1st class male" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `transform`\n", "Can apply such functions for all columns also using transform which transforms all rows\n" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedAgeSibSpParchFare
SexPclass
male3455.5158500.135447NaN0.4985590.22478412.661633
female1469.2127660.968085NaN0.5531910.457447106.125798
3399.7291670.500000NaN0.8958330.79861116.118810
1469.2127660.968085NaN0.5531910.457447106.125798
male3455.5158500.135447NaN0.4985590.22478412.661633
\n", "
" ], "text/plain": [ " PassengerId Survived Age SibSp Parch Fare\n", "Sex Pclass \n", "male 3 455.515850 0.135447 NaN 0.498559 0.224784 12.661633\n", "female 1 469.212766 0.968085 NaN 0.553191 0.457447 106.125798\n", " 3 399.729167 0.500000 NaN 0.895833 0.798611 16.118810\n", " 1 469.212766 0.968085 NaN 0.553191 0.457447 106.125798\n", "male 3 455.515850 0.135447 NaN 0.498559 0.224784 12.661633" ] }, "execution_count": 153, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# shape of below code is same as original df\n", "\n", "df_index.groupby(level=[0,1]).transform(lambda x: sum(x)/len(x)).head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Handling missing data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `dropna`\n", "Drop rows with na" ] }, { "cell_type": "code", "execution_count": 156, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(183, 12)" ] }, "execution_count": 156, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# how=any -> row with any column = NA\n", "\n", "df.dropna(axis=0, how='any').shape" ] }, { "cell_type": "code", "execution_count": 159, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(891, 12)" ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# how=any -> row with all columns = NA\n", "\n", "df.dropna(axis=0, how='all').shape" ] }, { "cell_type": "code", "execution_count": 167, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'Age', 'Cabin', 'Embarked'}]" ] }, "execution_count": 167, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# drops column which have any row of NA\n", "\n", "[set(df.columns) - set(df.dropna(axis=1, how='any').columns)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Three columns have been removed" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `fillna`" ] }, { "cell_type": "code", "execution_count": 173, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale2210A/5 211717.25<function mean at 0x10c7d7d90>S
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass Name Sex Age SibSp \\\n", "0 1 0 3 Braund, Mr. Owen Harris male 22 1 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "0 0 A/5 21171 7.25 S " ] }, "execution_count": 173, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# replace with mean of that column\n", "# can put any specific value also\n", "# would not work for columns with string type like Cabin\n", "\n", "df.fillna(np.mean)[:1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Combining Data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Drawing\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `merge` / `join`\n", "\n", "* **how** = 'left', 'right', 'outer', 'inner'\n", "* **on**\n" ] }, { "cell_type": "code", "execution_count": 182, "metadata": {}, "outputs": [], "source": [ "data1 = pd.DataFrame({'x1': list('abc'), 'x2': [11.432, 1.303, 99.906]})" ] }, { "cell_type": "code", "execution_count": 197, "metadata": {}, "outputs": [], "source": [ "data2 = pd.DataFrame({'x1': list('abd'), 'x3': [20.784, np.NaN, 20.784]})" ] }, { "cell_type": "code", "execution_count": 183, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2
0a11.432
1b1.303
2c99.906
\n", "
" ], "text/plain": [ " x1 x2\n", "0 a 11.432\n", "1 b 1.303\n", "2 c 99.906" ] }, "execution_count": 183, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data1" ] }, { "cell_type": "code", "execution_count": 198, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x3
0a20.784
1bNaN
2d20.784
\n", "
" ], "text/plain": [ " x1 x3\n", "0 a 20.784\n", "1 b NaN\n", "2 d 20.784" ] }, "execution_count": 198, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data2" ] }, { "cell_type": "code", "execution_count": 199, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2x3
0a11.43220.784
1b1.303NaN
\n", "
" ], "text/plain": [ " x1 x2 x3\n", "0 a 11.432 20.784\n", "1 b 1.303 NaN" ] }, "execution_count": 199, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# inner join when both table have that key (like sql)\n", "\n", "data1.merge(data2, how='inner', on='x1')" ] }, { "cell_type": "code", "execution_count": 200, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2x3
0a11.43220.784
1b1.303NaN
2c99.906NaN
3dNaN20.784
\n", "
" ], "text/plain": [ " x1 x2 x3\n", "0 a 11.432 20.784\n", "1 b 1.303 NaN\n", "2 c 99.906 NaN\n", "3 d NaN 20.784" ] }, "execution_count": 200, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# outer joins on all keys in both df and creates NA\n", "\n", "data1.merge(data2, how='outer', on='x1')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "can also use `join` but `merge` is faster. just use merge" ] }, { "cell_type": "code", "execution_count": 202, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1Lx2x1x3
0a11.432NaNNaN
1b1.303NaNNaN
2c99.906NaNNaN
\n", "
" ], "text/plain": [ " x1L x2 x1 x3\n", "0 a 11.432 NaN NaN\n", "1 b 1.303 NaN NaN\n", "2 c 99.906 NaN NaN" ] }, "execution_count": 202, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# if columns overlap, have to specify suffix as it makes for all\n", "\n", "data1.join(data2, on='x1', how='left', lsuffix='L')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `concatenate`" ] }, { "cell_type": "code", "execution_count": 223, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2x3
0a11.432NaN
1b1.303NaN
2c99.906NaN
0aNaN20.784
1bNaNNaN
2dNaN20.784
3gNaN500.000
\n", "
" ], "text/plain": [ " x1 x2 x3\n", "0 a 11.432 NaN\n", "1 b 1.303 NaN\n", "2 c 99.906 NaN\n", "0 a NaN 20.784\n", "1 b NaN NaN\n", "2 d NaN 20.784\n", "3 g NaN 500.000" ] }, "execution_count": 223, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# join over axis=0, i.e rows combine \n", "# also adds all columns with na\n", "\n", "pd.concat([data1, data2], axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that it has index duplicates as it maintain original df index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can use `ignore_index=True` to make index start from 0" ] }, { "cell_type": "code", "execution_count": 211, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2x3
0a11.432NaN
1b1.303NaN
2c99.906NaN
3aNaN20.784
4bNaNNaN
5dNaN20.784
\n", "
" ], "text/plain": [ " x1 x2 x3\n", "0 a 11.432 NaN\n", "1 b 1.303 NaN\n", "2 c 99.906 NaN\n", "3 a NaN 20.784\n", "4 b NaN NaN\n", "5 d NaN 20.784" ] }, "execution_count": 211, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([data1, data2], axis=0, ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 217, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x3
0a20.784
1bNaN
2d20.784
3g500.000
\n", "
" ], "text/plain": [ " x1 x3\n", "0 a 20.784\n", "1 b NaN\n", "2 d 20.784\n", "3 g 500.000" ] }, "execution_count": 217, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data2.loc[3] = ['g', 500] # adding new row\n", "data2" ] }, { "cell_type": "code", "execution_count": 228, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2x1x3
0a11.432a20.784
1b1.303bNaN
2c99.906d20.784
3NaNNaNg500.000
\n", "
" ], "text/plain": [ " x1 x2 x1 x3\n", "0 a 11.432 a 20.784\n", "1 b 1.303 b NaN\n", "2 c 99.906 d 20.784\n", "3 NaN NaN g 500.000" ] }, "execution_count": 228, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# join over axis=1, i.e columns combine \n", "\n", "pd.concat([data1, data2], axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Date formatting\n", "\n", "* `to_datetime()` -> convert whatever format argument to datetime (obviously that can be parsed to datetime)\n", "* `date_range()` -> generates datetime data\n", "* `Datetimeindex` -> datetypeindex data" ] }, { "cell_type": "code", "execution_count": 246, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Timestamp('2018-02-19 00:00:00')" ] }, "execution_count": 246, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.to_datetime('2018-2-19')" ] }, { "cell_type": "code", "execution_count": 250, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2018-04-18', '2018-04-19', '2018-04-20', '2018-04-21',\n", " '2018-04-22', '2018-04-23'],\n", " dtype='datetime64[ns]', freq='D')" ] }, "execution_count": 250, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# gives datetimeindex format\n", "\n", "pd.date_range('2018-4-18', periods=6, freq='d')" ] }, { "cell_type": "code", "execution_count": 235, "metadata": {}, "outputs": [], "source": [ "data1['date'] = pd.date_range('2018-4-18', periods=3, freq='d')" ] }, { "cell_type": "code", "execution_count": 236, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x1x2date
0a11.4322018-04-18
1b1.3032018-04-19
2c99.9062018-04-20
\n", "
" ], "text/plain": [ " x1 x2 date\n", "0 a 11.432 2018-04-18\n", "1 b 1.303 2018-04-19\n", "2 c 99.906 2018-04-20" ] }, "execution_count": 236, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data1" ] }, { "cell_type": "code", "execution_count": 248, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2018-04-18\n", "1 2018-04-19\n", "2 2018-04-20\n", "Name: date, dtype: datetime64[ns]" ] }, "execution_count": 248, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data1.date" ] }, { "cell_type": "code", "execution_count": 247, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2018-04-18', '2018-04-19', '2018-04-20'], dtype='datetime64[ns]', name='date', freq=None)" ] }, "execution_count": 247, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.DatetimeIndex(data1.date)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Reshaping data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `pivot` -> reshape data\n", "Ever used pivot table in excel? It's same. " ] }, { "cell_type": "code", "execution_count": 252, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerId12345678910...882883884885886887888889890891
Sex
femaleNaN38.026.035.0NaNNaNNaNNaN27.014.0...NaN22.0NaNNaN39.0NaN19.0NaNNaNNaN
male22.0NaNNaNNaN35.0NaN54.02.0NaNNaN...33.0NaN28.025.0NaN27.0NaNNaN26.032.0
\n", "

2 rows × 891 columns

\n", "
" ], "text/plain": [ "PassengerId 1 2 3 4 5 6 7 8 9 10 ... \\\n", "Sex ... \n", "female NaN 38.0 26.0 35.0 NaN NaN NaN NaN 27.0 14.0 ... \n", "male 22.0 NaN NaN NaN 35.0 NaN 54.0 2.0 NaN NaN ... \n", "\n", "PassengerId 882 883 884 885 886 887 888 889 890 891 \n", "Sex \n", "female NaN 22.0 NaN NaN 39.0 NaN 19.0 NaN NaN NaN \n", "male 33.0 NaN 28.0 25.0 NaN 27.0 NaN NaN 26.0 32.0 \n", "\n", "[2 rows x 891 columns]" ] }, "execution_count": 252, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# index = new index, columns = new_columns, values = values to put\n", "\n", "df.pivot(index='Sex', columns = 'PassengerId', values = 'Age')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In above case, use of pivot doesn't make sense but this is just an example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `stack` \n", "\n", "Convert whole df into 1 long format" ] }, { "cell_type": "code", "execution_count": 258, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 PassengerId 1\n", " Survived 0\n", " Pclass 3\n", " Name Braund, Mr. Owen Harris\n", " Sex male\n", " Age 22\n", " SibSp 1\n", " Parch 0\n", " Ticket A/5 21171\n", " Fare 7.25\n", " Embarked S\n", "1 PassengerId 2\n", " Survived 1\n", " Pclass 1\n", " Name Cumings, Mrs. John Bradley (Florence Briggs Th...\n", " Sex female\n", " Age 38\n", " SibSp 1\n", " Parch 0\n", " Ticket PC 17599\n", " Fare 71.2833\n", " Cabin C85\n", " Embarked C\n", "2 PassengerId 3\n", " Survived 1\n", " Pclass 3\n", " Name Heikkinen, Miss. Laina\n", " Sex female\n", " Age 26\n", " SibSp 0\n", " ... \n", "888 Name Johnston, Miss. Catherine Helen \"Carrie\"\n", " Sex female\n", " SibSp 1\n", " Parch 2\n", " Ticket W./C. 6607\n", " Fare 23.45\n", " Embarked S\n", "889 PassengerId 890\n", " Survived 1\n", " Pclass 1\n", " Name Behr, Mr. Karl Howell\n", " Sex male\n", " Age 26\n", " SibSp 0\n", " Parch 0\n", " Ticket 111369\n", " Fare 30\n", " Cabin C148\n", " Embarked C\n", "890 PassengerId 891\n", " Survived 0\n", " Pclass 3\n", " Name Dooley, Mr. Patrick\n", " Sex male\n", " Age 32\n", " SibSp 0\n", " Parch 0\n", " Ticket 370376\n", " Fare 7.75\n", " Embarked Q\n", "Length: 9826, dtype: object" ] }, "execution_count": 258, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.stack()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You won't generally use it. I have never come across its use over my experience with python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Iteration\n", "To get column/row indexes, series pair. \n", "\n", "* `iteritems()` for column-index, series\n", "* `iterrows()` for row-index, series" ] }, { "cell_type": "code", "execution_count": 286, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[(0, 'male'), (1, 'female'), (2, 'female'), (3, 'female'), (4, 'male')]" ] }, "execution_count": 286, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(df.Sex.iteritems())[:5]" ] }, { "cell_type": "code", "execution_count": 285, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0, PassengerId 1\n", " Survived 0\n", " Pclass 3\n", " Name Braund, Mr. Owen Harris\n", " Sex male\n", " Age 22\n", " SibSp 1\n", " Parch 0\n", " Ticket A/5 21171\n", " Fare 7.25\n", " Cabin NaN\n", " Embarked S\n", " Name: 0, dtype: object)" ] }, "execution_count": 285, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(df.iterrows())[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Apply functions\n", "\n", "* `apply` -> apply function over df\n", "* `apply_map` -> apply function elementwise (for each series of df. think of column wise)" ] }, { "cell_type": "code", "execution_count": 338, "metadata": {}, "outputs": [], "source": [ "# function squares when type(x) = float, cubes when type(x) = int, return same when other\n", "\n", "f = lambda x: x**2 if type(x) == float else x**3 if type(x) == int else x\n" ] }, { "cell_type": "code", "execution_count": 335, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 52.562500\n", "1 5081.308859\n", "2 62.805625\n", "Name: Fare, dtype: float64" ] }, "execution_count": 335, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# whole series is passed\n", "\n", "df.Fare.apply(f)[:3]" ] }, { "cell_type": "code", "execution_count": 339, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
01027Braund, Mr. Owen Harrismale484.010A/5 2117152.562500NaNS
1811Cumings, Mrs. John Bradley (Florence Briggs Th...female1444.010PC 175995081.308859C85C
227127Heikkinen, Miss. Lainafemale676.000STON/O2. 310128262.805625NaNS
\n", "
" ], "text/plain": [ " PassengerId Survived Pclass \\\n", "0 1 0 27 \n", "1 8 1 1 \n", "2 27 1 27 \n", "\n", " Name Sex Age SibSp \\\n", "0 Braund, Mr. Owen Harris male 484.0 1 \n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 1444.0 1 \n", "2 Heikkinen, Miss. Laina female 676.0 0 \n", "\n", " Parch Ticket Fare Cabin Embarked \n", "0 0 A/5 21171 52.562500 NaN S \n", "1 0 PC 17599 5081.308859 C85 C \n", "2 0 STON/O2. 3101282 62.805625 NaN S " ] }, "execution_count": 339, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# elements are passed\n", "\n", "df.applymap(f)[:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Working with text data\n", "What all can we do when we have string datatype in pandas dataframe/series ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### `str` \n", "\n", "Working with string format in pandas series/df \n", "\n", "We can do:\n", "* `str.upper()/lower()` to convert string into upper or lower case\n", "* `str.len()` to find the length of sting\n", "* `str.strip()/lstrip()/rstrip()` to strip spaces\n", "* `str.replace()` to replace anything from string\n", "* `str.split()` to split words of string or using some other delimiter\n", "* `str.get()` to access elements in slit list \n", "* `str.resplit()` spit in reverse order of string based on some delimiter\n", "* `str.extract()` extract specific thing from string. alphabet or number\n", "\n", "Let's see how to use all that in pandas series. Keep in mind pandas DataFrame has no attribute called `str` and works on Series object only. So, grab column of df, then apply `str`\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 braund, mr. owen harris\n", "1 cumings, mrs. john bradley (florence briggs th...\n", "2 heikkinen, miss. laina\n", "3 futrelle, mrs. jacques heath (lily may peel)\n", "4 allen, mr. william henry\n", "Name: Name, dtype: object" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# converts all rows into lower\n", "\n", "df.Name.str.lower().head()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 MALE\n", "1 FEMALE\n", "2 FEMALE\n", "3 FEMALE\n", "4 MALE\n", "Name: Sex, dtype: object" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# converts all rows into upper \n", "\n", "df.Sex.str.upper().head()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 23\n", "1 51\n", "2 22\n", "3 44\n", "4 24\n", "Name: Name, dtype: int64" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# counts all the characters including spaces\n", "\n", "df.Name.str.len().head()" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
First_NameLast_Name
0BraundMr. Owen Harris
1CumingsMrs. John Bradley (Florence Briggs Thayer)
2HeikkinenMiss. Laina
3FutrelleMrs. Jacques Heath (Lily May Peel)
4AllenMr. William Henry
\n", "
" ], "text/plain": [ " First_Name Last_Name\n", "0 Braund Mr. Owen Harris\n", "1 Cumings Mrs. John Bradley (Florence Briggs Thayer)\n", "2 Heikkinen Miss. Laina\n", "3 Futrelle Mrs. Jacques Heath (Lily May Peel)\n", "4 Allen Mr. William Henry" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# splits strings in each row over whitespaces ()\n", "# expand=True : expand columns\n", "# pat = regex to split on\n", "\n", "df.Name.str.split(pat=',',expand=True).head().rename(columns={0:'First_Name', 1: 'Last_Name'})" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 [Braund,, Mr., Owen, Harris]\n", "1 [Cumings,, Mrs., John, Bradley, (Florence, Bri...\n", "2 [Heikkinen,, Miss., Laina]\n", "3 [Futrelle,, Mrs., Jacques, Heath, (Lily, May, ...\n", "4 [Allen,, Mr., William, Henry]\n", "Name: Name, dtype: object" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# splits strings in each row over whitespaces ()\n", "# expand=False : doesn't expand columns\n", "# pat = regex to split on\n", "\n", "df.Name.str.split(expand=False).head()" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Braund, Owen Harris\n", "1 Cumings, . John Bradley (Florence Briggs Thayer)\n", "2 Heikkinen, Miss. Laina\n", "3 Futrelle, . Jacques Heath (Lily May Peel)\n", "4 Allen, William Henry\n", "Name: Name, dtype: object" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# replace Mr. with empty space\n", "\n", "df.Name.str.replace('Mr.', '').head()" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Cumings,', 'Mrs.', 'John', 'Bradley', '(Florence', 'Briggs', 'Thayer)']" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get() is used to get particular row of split\n", "\n", "df.Name.str.split().get(1)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 Braund, Mr. Owen Harris\n", "1 Cumings, Mrs. John Bradley (Florence Briggs Th...\n", "2 Heikkinen, Miss. Laina\n", "3 Futrelle, Mrs. Jacques Heath (Lily May Peel)\n", "4 Allen, Mr. William Henry\n", "5 Moran, Mr. James\n", "6 McCarthy, Mr. Timothy J\n", "7 Palsson, Master. Gosta Leonard\n", "8 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)\n", "9 Nasser, Mrs. Nicholas (Adele Achem)\n", "Name: Name, dtype: object" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.Name[:10]" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Last_Name
0Braund
1Cumings
2Heikkinen
3Futrelle
4Allen
\n", "
" ], "text/plain": [ " Last_Name\n", "0 Braund\n", "1 Cumings\n", "2 Heikkinen\n", "3 Futrelle\n", "4 Allen" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Extract just last name\n", "\n", "df.Name.str.extract('(?P[a-zA-Z]+)', expand=True).head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### End" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }