{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Intro to Pandas\n", "\n", "This is a short introduction to pandas based on the [10 Minutes to pandas](http://pandas.pydata.org/pandas-docs/stable/10min.html) geared mainly for new users along with a few addition based on the [Cookbook](http://pandas.pydata.org/pandas-docs/stable/cookbook.html#cookbook) recipes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Customarily, we import as follows:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Object Creation\n", "\n", "See the [Data Structure Intro section](http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dsintro) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Series\n", "Creating a Series by passing a list of values, letting pandas create a default integer index:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "s = pd.Series([1,3,5,np.nan,6,8])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Series is very similar to numpy array but the index of a series is an additional class attribute" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1., 3., 5., nan, 6., 8.])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.values # values of the series - a numpy arry" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "RangeIndex(start=0, stop=6, step=1)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.index # index of the series" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dataframes\n", "\n", "Creating a DataFrame by passing a numpy array, with a datetime index and labeled columns:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "dates = pd.date_range('20130101', periods=6)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',\n", " '2013-01-05', '2013-01-06'],\n", " dtype='datetime64[ns]', freq='D')" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dates" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A Dataframe has:\n", " - index\n", " - values\n", " - column names\n", " - is a generalization of an excel table" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))" ] }, { "cell_type": "code", "execution_count": 11, "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", "
ABCD
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-02-0.480141-1.1375060.2376691.733485
2013-01-031.099803-3.3868720.3984901.205075
2013-01-040.9305610.208805-1.1041760.423279
2013-01-05-0.078533-0.9558050.3646630.854699
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Creating a DataFrame by passing a dict of objects that can be converted to series-like." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "df2 = pd.DataFrame({'A':1.,\n", " 'B':pd.Timestamp('20130102'),\n", " 'C':pd.Series(1,index=list(range(4)),dtype='float32'),\n", " 'D':np.array([3]*4,dtype='int32'),\n", " 'E':pd.Categorical([\"test\",\"train\",\"test\",\"train\"]),\n", " 'F':'foo'})" ] }, { "cell_type": "code", "execution_count": 13, "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", "
ABCDEF
01.02013-01-021.03testfoo
11.02013-01-021.03trainfoo
21.02013-01-021.03testfoo
31.02013-01-021.03trainfoo
\n", "
" ], "text/plain": [ " A B C D E F\n", "0 1.0 2013-01-02 1.0 3 test foo\n", "1 1.0 2013-01-02 1.0 3 train foo\n", "2 1.0 2013-01-02 1.0 3 test foo\n", "3 1.0 2013-01-02 1.0 3 train foo" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Having specific [dtypes](http://pandas.pydata.org/pandas-docs/stable/basics.html#basics-dtypes)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A float64\n", "B datetime64[ns]\n", "C float32\n", "D int32\n", "E category\n", "F object\n", "dtype: object" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2.dtypes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Viewing Data\n", "\n", "See the [Basics section](http://pandas.pydata.org/pandas-docs/stable/basics.html#basics) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See the top & bottom rows of the frame" ] }, { "cell_type": "code", "execution_count": 15, "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", "
ABCD
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-02-0.480141-1.1375060.2376691.733485
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head(2)" ] }, { "cell_type": "code", "execution_count": 16, "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", "
ABCD
2013-01-05-0.078533-0.9558050.3646630.854699
2013-01-06-1.411446-1.7886921.133534-0.126493
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699\n", "2013-01-06 -1.411446 -1.788692 1.133534 -0.126493" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.tail(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Display the index, columns, and the underlying numpy data" ] }, { "cell_type": "code", "execution_count": 17, "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", "
indexBCD
A
-1.4114462013-01-06-1.7886921.133534-0.126493
-0.4801412013-01-02-1.1375060.2376691.733485
-0.0785332013-01-05-0.9558050.3646630.854699
0.0565732013-01-010.159333-0.054955-0.826575
0.9305612013-01-040.208805-1.1041760.423279
1.0998032013-01-03-3.3868720.3984901.205075
\n", "
" ], "text/plain": [ " index B C D\n", "A \n", "-1.411446 2013-01-06 -1.788692 1.133534 -0.126493\n", "-0.480141 2013-01-02 -1.137506 0.237669 1.733485\n", "-0.078533 2013-01-05 -0.955805 0.364663 0.854699\n", " 0.056573 2013-01-01 0.159333 -0.054955 -0.826575\n", " 0.930561 2013-01-04 0.208805 -1.104176 0.423279\n", " 1.099803 2013-01-03 -3.386872 0.398490 1.205075" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.reset_index().set_index('A').sort_index()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['A', 'B', 'C', 'D'], dtype='object')" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.columns" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.05657336, 0.1593327 , -0.05495525, -0.82657504],\n", " [-0.48014086, -1.13750637, 0.23766922, 1.73348476],\n", " [ 1.09980257, -3.38687165, 0.39848999, 1.2050749 ],\n", " [ 0.93056107, 0.20880502, -1.10417636, 0.42327943],\n", " [-0.07853279, -0.95580454, 0.3646634 , 0.85469944],\n", " [-1.41144632, -1.78869246, 1.13353423, -0.12649259]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.values # returns a numpy array" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Describe shows a quick statistic summary of the numeric columns of the data" ] }, { "cell_type": "code", "execution_count": 20, "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", "
ABCD
count6.0000006.0000006.0000006.000000
mean0.019470-1.1501230.1625380.543912
std0.9279351.3423930.7344220.926395
min-1.411446-3.386872-1.104176-0.826575
25%-0.379739-1.6258960.0182010.010950
50%-0.010980-1.0466550.3011660.638989
75%0.712064-0.1194520.3900331.117481
max1.0998030.2088051.1335341.733485
\n", "
" ], "text/plain": [ " A B C D\n", "count 6.000000 6.000000 6.000000 6.000000\n", "mean 0.019470 -1.150123 0.162538 0.543912\n", "std 0.927935 1.342393 0.734422 0.926395\n", "min -1.411446 -3.386872 -1.104176 -0.826575\n", "25% -0.379739 -1.625896 0.018201 0.010950\n", "50% -0.010980 -1.046655 0.301166 0.638989\n", "75% 0.712064 -0.119452 0.390033 1.117481\n", "max 1.099803 0.208805 1.133534 1.733485" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Transposing your data" ] }, { "cell_type": "code", "execution_count": 21, "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", "
2013-01-012013-01-022013-01-032013-01-042013-01-052013-01-06
A0.056573-0.4801411.0998030.930561-0.078533-1.411446
B0.159333-1.137506-3.3868720.208805-0.955805-1.788692
C-0.0549550.2376690.398490-1.1041760.3646631.133534
D-0.8265751.7334851.2050750.4232790.854699-0.126493
\n", "
" ], "text/plain": [ " 2013-01-01 2013-01-02 2013-01-03 2013-01-04 2013-01-05 2013-01-06\n", "A 0.056573 -0.480141 1.099803 0.930561 -0.078533 -1.411446\n", "B 0.159333 -1.137506 -3.386872 0.208805 -0.955805 -1.788692\n", "C -0.054955 0.237669 0.398490 -1.104176 0.364663 1.133534\n", "D -0.826575 1.733485 1.205075 0.423279 0.854699 -0.126493" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sorting by an axis" ] }, { "cell_type": "code", "execution_count": 22, "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", "
BCD
dateA
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-02-0.480141-1.1375060.2376691.733485
2013-01-031.099803-3.3868720.3984901.205075
2013-01-040.9305610.208805-1.1041760.423279
2013-01-05-0.078533-0.9558050.3646630.854699
2013-01-06-1.411446-1.7886921.133534-0.126493
\n", "
" ], "text/plain": [ " B C D\n", "date A \n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699\n", "2013-01-06 -1.411446 -1.788692 1.133534 -0.126493" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.reset_index().rename(columns={'index':'date'}).set_index(['date', 'A']).sort_index(axis=0, ascending=True)" ] }, { "cell_type": "code", "execution_count": 23, "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", "
DCBA
2013-01-01-0.826575-0.0549550.1593330.056573
2013-01-021.7334850.237669-1.137506-0.480141
2013-01-031.2050750.398490-3.3868721.099803
2013-01-040.423279-1.1041760.2088050.930561
2013-01-050.8546990.364663-0.955805-0.078533
2013-01-06-0.1264931.133534-1.788692-1.411446
\n", "
" ], "text/plain": [ " D C B A\n", "2013-01-01 -0.826575 -0.054955 0.159333 0.056573\n", "2013-01-02 1.733485 0.237669 -1.137506 -0.480141\n", "2013-01-03 1.205075 0.398490 -3.386872 1.099803\n", "2013-01-04 0.423279 -1.104176 0.208805 0.930561\n", "2013-01-05 0.854699 0.364663 -0.955805 -0.078533\n", "2013-01-06 -0.126493 1.133534 -1.788692 -1.411446" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_index(axis=1, ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sorting by value" ] }, { "cell_type": "code", "execution_count": 24, "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", "
ABCD
2013-01-040.9305610.208805-1.1041760.423279
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-05-0.078533-0.9558050.3646630.854699
2013-01-02-0.480141-1.1375060.2376691.733485
2013-01-06-1.411446-1.7886921.133534-0.126493
2013-01-031.099803-3.3868720.3984901.205075
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485\n", "2013-01-06 -1.411446 -1.788692 1.133534 -0.126493\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by='B', ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Selection" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note:** While standard Python / Numpy expressions for selecting and setting are intuitive and come in handy for interactive work, for production code, we recommend the optimized pandas data access methods, .at, .iat, .loc, .iloc and .ix." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See the indexing documentation [Indexing and Selecting Data](http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing) and [MultiIndex / Advanced Indexing](http://pandas.pydata.org/pandas-docs/stable/advanced.html#advanced)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Getting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Selecting a single column, which yields a Series, equivalent to df.A" ] }, { "cell_type": "code", "execution_count": 25, "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", "
ABCD
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-02-0.480141-1.1375060.2376691.733485
2013-01-031.099803-3.3868720.3984901.205075
2013-01-040.9305610.208805-1.1041760.423279
2013-01-05-0.078533-0.9558050.3646630.854699
2013-01-06-1.411446-1.7886921.133534-0.126493
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699\n", "2013-01-06 -1.411446 -1.788692 1.133534 -0.126493" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2013-01-01 0.056573\n", "2013-01-02 -0.480141\n", "2013-01-03 1.099803\n", "2013-01-04 0.930561\n", "2013-01-05 -0.078533\n", "2013-01-06 -1.411446\n", "Freq: D, Name: A, dtype: float64" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['A']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Selecting via [], which slices the rows." ] }, { "cell_type": "code", "execution_count": 27, "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", "
ABCD
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-02-0.480141-1.1375060.2376691.733485
2013-01-031.099803-3.3868720.3984901.205075
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[0:3]" ] }, { "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", "
ABCD
2013-01-02-0.480141-1.1375060.2376691.733485
2013-01-031.099803-3.3868720.3984901.205075
2013-01-040.9305610.208805-1.1041760.423279
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-02 -0.480141 -1.137506 0.237669 1.733485\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['20130102':'20130104']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Selection by Label\n", "\n", "See more in [Selection by Label](Selection by Label)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For getting a cross section using a label" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A 0.056573\n", "B 0.159333\n", "C -0.054955\n", "D -0.826575\n", "Name: 2013-01-01 00:00:00, dtype: float64" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[dates[0]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Selection by Label" ] }, { "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", "
AB
2013-01-010.0565730.159333
2013-01-02-0.480141-1.137506
2013-01-031.099803-3.386872
2013-01-040.9305610.208805
2013-01-05-0.078533-0.955805
2013-01-06-1.411446-1.788692
\n", "
" ], "text/plain": [ " A B\n", "2013-01-01 0.056573 0.159333\n", "2013-01-02 -0.480141 -1.137506\n", "2013-01-03 1.099803 -3.386872\n", "2013-01-04 0.930561 0.208805\n", "2013-01-05 -0.078533 -0.955805\n", "2013-01-06 -1.411446 -1.788692" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[:,['A','B']] # select all rows and column A, B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Showing label slicing, both endpoints are included" ] }, { "cell_type": "code", "execution_count": 32, "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", "
AB
2013-01-02-0.480141-1.137506
2013-01-031.099803-3.386872
2013-01-040.9305610.208805
\n", "
" ], "text/plain": [ " A B\n", "2013-01-02 -0.480141 -1.137506\n", "2013-01-03 1.099803 -3.386872\n", "2013-01-04 0.930561 0.208805" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc['20130102':'20130104',['A','B']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reduction in the dimensions of the returned object" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "df.loc['20130102',['A','B']] = 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For getting a scalar value" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.056573358267329496" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[dates[0],'A']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Selection by Position\n", "\n", "See more in [Selection by Position](http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-integer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Select via the position of the passed integers" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A 0.930561\n", "B 0.208805\n", "C -1.104176\n", "D 0.423279\n", "Name: 2013-01-04 00:00:00, dtype: float64" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By integer slices, acting similar to numpy/python" ] }, { "cell_type": "code", "execution_count": 38, "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", "
AB
2013-01-040.9305610.208805
2013-01-05-0.078533-0.955805
\n", "
" ], "text/plain": [ " A B\n", "2013-01-04 0.930561 0.208805\n", "2013-01-05 -0.078533 -0.955805" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[3:5,0:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By lists of integer position locations, similar to the numpy/python style" ] }, { "cell_type": "code", "execution_count": 39, "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", "
AC
2013-01-021.0000000.237669
2013-01-031.0998030.398490
2013-01-05-0.0785330.364663
\n", "
" ], "text/plain": [ " A C\n", "2013-01-02 1.000000 0.237669\n", "2013-01-03 1.099803 0.398490\n", "2013-01-05 -0.078533 0.364663" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[[1,2,4],[0,2]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For slicing rows explicitly" ] }, { "cell_type": "code", "execution_count": 40, "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", "
ABCD
2013-01-021.0000001.0000000.2376691.733485
2013-01-031.099803-3.3868720.3984901.205075
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-02 1.000000 1.000000 0.237669 1.733485\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[1:3,:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For slicing columns explicitly" ] }, { "cell_type": "code", "execution_count": 41, "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", "
BC
2013-01-010.159333-0.054955
2013-01-021.0000000.237669
2013-01-03-3.3868720.398490
2013-01-040.208805-1.104176
2013-01-05-0.9558050.364663
2013-01-06-1.7886921.133534
\n", "
" ], "text/plain": [ " B C\n", "2013-01-01 0.159333 -0.054955\n", "2013-01-02 1.000000 0.237669\n", "2013-01-03 -3.386872 0.398490\n", "2013-01-04 0.208805 -1.104176\n", "2013-01-05 -0.955805 0.364663\n", "2013-01-06 -1.788692 1.133534" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[:,1:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For getting a value explicitly" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[1,1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For getting fast access to a scalar (equiv to the prior method)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iat[1,1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Boolean Indexing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using a single column’s values to select data." ] }, { "cell_type": "code", "execution_count": 49, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCD
2013-01-010.0565730.159333-0.054955-0.826575
2013-01-021.0000001.0000000.2376691.733485
2013-01-040.9305610.208805-1.1041760.423279
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575\n", "2013-01-02 1.000000 1.000000 0.237669 1.733485\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[df.B > 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A where operation for getting." ] }, { "cell_type": "code", "execution_count": 50, "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", "
ABCD
2013-01-010.0565730.159333NaNNaN
2013-01-021.0000001.0000000.2376691.733485
2013-01-031.099803NaN0.3984901.205075
2013-01-040.9305610.208805NaN0.423279
2013-01-05NaNNaN0.3646630.854699
2013-01-06NaNNaN1.133534NaN
\n", "
" ], "text/plain": [ " A B C D\n", "2013-01-01 0.056573 0.159333 NaN NaN\n", "2013-01-02 1.000000 1.000000 0.237669 1.733485\n", "2013-01-03 1.099803 NaN 0.398490 1.205075\n", "2013-01-04 0.930561 0.208805 NaN 0.423279\n", "2013-01-05 NaN NaN 0.364663 0.854699\n", "2013-01-06 NaN NaN 1.133534 NaN" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[df > 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using the isin() method for filtering:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "scrolled": true }, "outputs": [], "source": [ "df2 = df.copy()" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "df2['E'] = ['one','one', 'two','three','four','three']" ] }, { "cell_type": "code", "execution_count": 53, "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", "
ABCDE
2013-01-010.0565730.159333-0.054955-0.826575one
2013-01-021.0000001.0000000.2376691.733485one
2013-01-031.099803-3.3868720.3984901.205075two
2013-01-040.9305610.208805-1.1041760.423279three
2013-01-05-0.078533-0.9558050.3646630.854699four
2013-01-06-1.411446-1.7886921.133534-0.126493three
\n", "
" ], "text/plain": [ " A B C D E\n", "2013-01-01 0.056573 0.159333 -0.054955 -0.826575 one\n", "2013-01-02 1.000000 1.000000 0.237669 1.733485 one\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075 two\n", "2013-01-04 0.930561 0.208805 -1.104176 0.423279 three\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699 four\n", "2013-01-06 -1.411446 -1.788692 1.133534 -0.126493 three" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2" ] }, { "cell_type": "code", "execution_count": 54, "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", "
ABCDE
2013-01-031.099803-3.3868720.3984901.205075two
2013-01-05-0.078533-0.9558050.3646630.854699four
\n", "
" ], "text/plain": [ " A B C D E\n", "2013-01-03 1.099803 -3.386872 0.398490 1.205075 two\n", "2013-01-05 -0.078533 -0.955805 0.364663 0.854699 four" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2[df2['E'].isin(['two','four'])]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Setting a new column automatically aligns the data by the indexes" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": [ "s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102',periods=6))" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2013-01-02 1\n", "2013-01-03 2\n", "2013-01-04 3\n", "2013-01-05 4\n", "2013-01-06 5\n", "2013-01-07 6\n", "Freq: D, dtype: int64" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s1" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "df['F'] = s1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Setting values by label" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "df.at[dates[0],'A'] = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Settomg values by position" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "df.iat[0,1] = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Setting by assigning with a numpy array" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "df.loc[:,'D'] = np.array([5] * len(df))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result of the prior setting operations" ] }, { "cell_type": "code", "execution_count": 61, "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", "
ABCDF
2013-01-010.0000000.000000-0.0549555NaN
2013-01-021.0000001.0000000.23766951.0
2013-01-031.099803-3.3868720.39849052.0
2013-01-040.9305610.208805-1.10417653.0
2013-01-05-0.078533-0.9558050.36466354.0
2013-01-06-1.411446-1.7886921.13353455.0
\n", "
" ], "text/plain": [ " A B C D F\n", "2013-01-01 0.000000 0.000000 -0.054955 5 NaN\n", "2013-01-02 1.000000 1.000000 0.237669 5 1.0\n", "2013-01-03 1.099803 -3.386872 0.398490 5 2.0\n", "2013-01-04 0.930561 0.208805 -1.104176 5 3.0\n", "2013-01-05 -0.078533 -0.955805 0.364663 5 4.0\n", "2013-01-06 -1.411446 -1.788692 1.133534 5 5.0" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A where operation with setting." ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [], "source": [ "df2 = df.copy()" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [], "source": [ "df2[df2 > 0] = -df2" ] }, { "cell_type": "code", "execution_count": 64, "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", "
ABCDF
2013-01-010.0000000.000000-0.054955-5NaN
2013-01-02-1.000000-1.000000-0.237669-5-1.0
2013-01-03-1.099803-3.386872-0.398490-5-2.0
2013-01-04-0.930561-0.208805-1.104176-5-3.0
2013-01-05-0.078533-0.955805-0.364663-5-4.0
2013-01-06-1.411446-1.788692-1.133534-5-5.0
\n", "
" ], "text/plain": [ " A B C D F\n", "2013-01-01 0.000000 0.000000 -0.054955 -5 NaN\n", "2013-01-02 -1.000000 -1.000000 -0.237669 -5 -1.0\n", "2013-01-03 -1.099803 -3.386872 -0.398490 -5 -2.0\n", "2013-01-04 -0.930561 -0.208805 -1.104176 -5 -3.0\n", "2013-01-05 -0.078533 -0.955805 -0.364663 -5 -4.0\n", "2013-01-06 -1.411446 -1.788692 -1.133534 -5 -5.0" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Missing Data\n", "\n", "pandas primarily uses the value np.nan to represent missing data. It is by default not included in computations. See the Missing Data section" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Reindexing allows you to change/add/delete the index on a specified axis. This returns a copy of the data." ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [], "source": [ "df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "df1.loc[dates[0]:dates[1],'E'] = 1" ] }, { "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABCDFE
2013-01-010.0000000.000000-0.0549555NaN1.0
2013-01-021.0000001.0000000.23766951.01.0
2013-01-031.099803-3.3868720.39849052.0NaN
2013-01-040.9305610.208805-1.10417653.0NaN
\n", "
" ], "text/plain": [ " A B C D F E\n", "2013-01-01 0.000000 0.000000 -0.054955 5 NaN 1.0\n", "2013-01-02 1.000000 1.000000 0.237669 5 1.0 1.0\n", "2013-01-03 1.099803 -3.386872 0.398490 5 2.0 NaN\n", "2013-01-04 0.930561 0.208805 -1.104176 5 3.0 NaN" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To drop any rows that have missing data." ] }, { "cell_type": "code", "execution_count": 68, "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", "
ABCDFE
2013-01-010.0000000.000000-0.0549555NaN1.0
2013-01-021.0000001.0000000.23766951.01.0
2013-01-031.099803-3.3868720.39849052.0NaN
2013-01-040.9305610.208805-1.10417653.0NaN
\n", "
" ], "text/plain": [ " A B C D F E\n", "2013-01-01 0.000000 0.000000 -0.054955 5 NaN 1.0\n", "2013-01-02 1.000000 1.000000 0.237669 5 1.0 1.0\n", "2013-01-03 1.099803 -3.386872 0.398490 5 2.0 NaN\n", "2013-01-04 0.930561 0.208805 -1.104176 5 3.0 NaN" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1.dropna(how='all', axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Filling missing data" ] }, { "cell_type": "code", "execution_count": 69, "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", "
ABCDFE
2013-01-010.0000000.000000-0.05495555.01.0
2013-01-021.0000001.0000000.23766951.01.0
2013-01-031.099803-3.3868720.39849052.05.0
2013-01-040.9305610.208805-1.10417653.05.0
\n", "
" ], "text/plain": [ " A B C D F E\n", "2013-01-01 0.000000 0.000000 -0.054955 5 5.0 1.0\n", "2013-01-02 1.000000 1.000000 0.237669 5 1.0 1.0\n", "2013-01-03 1.099803 -3.386872 0.398490 5 2.0 5.0\n", "2013-01-04 0.930561 0.208805 -1.104176 5 3.0 5.0" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1.fillna(value=5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the boolean mask where values are nan" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A 0\n", "B 0\n", "C 0\n", "D 0\n", "F 1\n", "E 2\n", "dtype: int64" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.isnull(df1).sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operations\n", "\n", "See the [Basic section on Binary Ops](http://pandas.pydata.org/pandas-docs/stable/basics.html#basics-binop)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Stats\n", "\n", "Operations in general exclude missing data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Performing a descriptive statistic" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A 1.099803\n", "B 1.000000\n", "C 1.133534\n", "D 5.000000\n", "F 5.000000\n", "dtype: float64" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.max()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Same operation on the other axis" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2013-01-01 1.236261\n", "2013-01-02 1.647534\n", "2013-01-03 1.022284\n", "2013-01-04 1.607038\n", "2013-01-05 1.666065\n", "2013-01-06 1.586679\n", "Freq: D, dtype: float64" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.mean(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Operating with objects that have different dimensionality and need alignment. In addition, pandas automatically broadcasts along the specified dimension." ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [], "source": [ "s = pd.Series([1,3,5,np.nan,6,8], index=dates)#.shift(2)" ] }, { "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", "
ABCDF
2013-01-01-1.000000-1.000000-1.0549554.0NaN
2013-01-02-2.000000-2.000000-2.7623312.0-2.0
2013-01-03-3.900197-8.386872-4.6015100.0-3.0
2013-01-04NaNNaNNaNNaNNaN
2013-01-05-6.078533-6.955805-5.635337-1.0-2.0
2013-01-06-9.411446-9.788692-6.866466-3.0-3.0
\n", "
" ], "text/plain": [ " A B C D F\n", "2013-01-01 -1.000000 -1.000000 -1.054955 4.0 NaN\n", "2013-01-02 -2.000000 -2.000000 -2.762331 2.0 -2.0\n", "2013-01-03 -3.900197 -8.386872 -4.601510 0.0 -3.0\n", "2013-01-04 NaN NaN NaN NaN NaN\n", "2013-01-05 -6.078533 -6.955805 -5.635337 -1.0 -2.0\n", "2013-01-06 -9.411446 -9.788692 -6.866466 -3.0 -3.0" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.subtract(s, axis='index')" ] }, { "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", "
ABCDF
2013-01-01-1.000000-1.000000-1.0549554.0NaN
2013-01-02-2.000000-2.000000-2.7623312.0-2.0
2013-01-03-3.900197-8.386872-4.6015100.0-3.0
2013-01-04NaNNaNNaNNaNNaN
2013-01-05-6.078533-6.955805-5.635337-1.0-2.0
2013-01-06-9.411446-9.788692-6.866466-3.0-3.0
\n", "
" ], "text/plain": [ " A B C D F\n", "2013-01-01 -1.000000 -1.000000 -1.054955 4.0 NaN\n", "2013-01-02 -2.000000 -2.000000 -2.762331 2.0 -2.0\n", "2013-01-03 -3.900197 -8.386872 -4.601510 0.0 -3.0\n", "2013-01-04 NaN NaN NaN NaN NaN\n", "2013-01-05 -6.078533 -6.955805 -5.635337 -1.0 -2.0\n", "2013-01-06 -9.411446 -9.788692 -6.866466 -3.0 -3.0" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sub(s, axis='index')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Apply" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Applying functions to the data" ] }, { "cell_type": "code", "execution_count": 79, "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", "
ABCDF
2013-01-010.0000000.000000-0.0549555NaN
2013-01-021.0000001.0000000.182714101.0
2013-01-032.099803-2.3868720.581204153.0
2013-01-043.030364-2.178067-0.522972206.0
2013-01-052.951831-3.133871-0.1583092510.0
2013-01-061.540385-4.9225640.9752253015.0
\n", "
" ], "text/plain": [ " A B C D F\n", "2013-01-01 0.000000 0.000000 -0.054955 5 NaN\n", "2013-01-02 1.000000 1.000000 0.182714 10 1.0\n", "2013-01-03 2.099803 -2.386872 0.581204 15 3.0\n", "2013-01-04 3.030364 -2.178067 -0.522972 20 6.0\n", "2013-01-05 2.951831 -3.133871 -0.158309 25 10.0\n", "2013-01-06 1.540385 -4.922564 0.975225 30 15.0" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.cumsum() # very useful for computing total returns" ] }, { "cell_type": "code", "execution_count": 80, "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", "
ABCDF
2013-01-010.0000000.000000-0.0549555NaN
2013-01-021.0000001.0000000.182714101.0
2013-01-032.099803-2.3868720.581204153.0
2013-01-043.030364-2.178067-0.522972206.0
2013-01-052.951831-3.133871-0.1583092510.0
2013-01-061.540385-4.9225640.9752253015.0
\n", "
" ], "text/plain": [ " A B C D F\n", "2013-01-01 0.000000 0.000000 -0.054955 5 NaN\n", "2013-01-02 1.000000 1.000000 0.182714 10 1.0\n", "2013-01-03 2.099803 -2.386872 0.581204 15 3.0\n", "2013-01-04 3.030364 -2.178067 -0.522972 20 6.0\n", "2013-01-05 2.951831 -3.133871 -0.158309 25 10.0\n", "2013-01-06 1.540385 -4.922564 0.975225 30 15.0" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.apply(np.cumsum)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A 2.511249\n", "B 4.386872\n", "C 2.237711\n", "D 0.000000\n", "F 4.000000\n", "dtype: float64" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.apply(lambda x: x.max() - x.min())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Histogramming\n", "\n", "See more at [Histogramming and Discretization](http://pandas.pydata.org/pandas-docs/stable/basics.html#basics-discretization)" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [], "source": [ "s = pd.Series(np.random.randint(0, 7, size=10))" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 6\n", "1 5\n", "2 1\n", "3 3\n", "4 1\n", "5 4\n", "6 0\n", "7 0\n", "8 2\n", "9 4\n", "dtype: int64" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 2\n", "1 2\n", "4 2\n", "2 1\n", "3 1\n", "5 1\n", "6 1\n", "dtype: int64" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.value_counts()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### String Methods\n", "\n", "Series is equipped with a set of string processing methods in the str attribute that make it easy to operate on each element of the array, as in the code snippet below. Note that pattern-matching in str generally uses [regular expressions](https://docs.python.org/2/library/re.html) by default (and in some cases always uses them). See more at [Vectorized String Methods](http://pandas.pydata.org/pandas-docs/stable/text.html#text-string-methods)." ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [], "source": [ "s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 A\n", "1 B\n", "2 C\n", "3 Aaba\n", "4 Baca\n", "5 NaN\n", "6 CABA\n", "7 dog\n", "8 cat\n", "dtype: object" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 a\n", "1 b\n", "2 c\n", "3 aaba\n", "4 baca\n", "5 NaN\n", "6 caba\n", "7 dog\n", "8 cat\n", "dtype: object" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.str.lower()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Merge" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Concat\n", "\n", "pandas provides various facilities for easily combining together Series, DataFrame, and Panel objects with various kinds of set logic for the indexes and relational algebra functionality in the case of join / merge-type operations.\n", "\n", "See the [Merging section](http://pandas.pydata.org/pandas-docs/stable/merging.html#merging)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Concatenating pandas objects together with concat():" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.randn(10, 4))" ] }, { "cell_type": "code", "execution_count": 89, "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", "
0123
01.0170960.583143-0.0295780.420775
1-1.3781940.443747-1.0566490.267996
20.6756360.288908-2.114351-1.957281
3-1.4943391.6225560.426388-1.876453
41.3488821.556022-0.490135-1.438133
5-1.830610-1.5033970.4983041.038869
60.246876-2.1754571.623862-0.734835
7-0.2370100.462616-0.6941090.914963
80.9613740.8451122.0627282.151655
90.324078-0.5823250.225703-1.164569
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.017096 0.583143 -0.029578 0.420775\n", "1 -1.378194 0.443747 -1.056649 0.267996\n", "2 0.675636 0.288908 -2.114351 -1.957281\n", "3 -1.494339 1.622556 0.426388 -1.876453\n", "4 1.348882 1.556022 -0.490135 -1.438133\n", "5 -1.830610 -1.503397 0.498304 1.038869\n", "6 0.246876 -2.175457 1.623862 -0.734835\n", "7 -0.237010 0.462616 -0.694109 0.914963\n", "8 0.961374 0.845112 2.062728 2.151655\n", "9 0.324078 -0.582325 0.225703 -1.164569" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[ 0 1 2 3\n", " 0 1.017096 0.583143 -0.029578 0.420775\n", " 1 -1.378194 0.443747 -1.056649 0.267996\n", " 2 0.675636 0.288908 -2.114351 -1.957281,\n", " 0 1 2 3\n", " 3 -1.494339 1.622556 0.426388 -1.876453\n", " 4 1.348882 1.556022 -0.490135 -1.438133\n", " 5 -1.830610 -1.503397 0.498304 1.038869\n", " 6 0.246876 -2.175457 1.623862 -0.734835,\n", " 0 1 2 3\n", " 7 -0.237010 0.462616 -0.694109 0.914963\n", " 8 0.961374 0.845112 2.062728 2.151655\n", " 9 0.324078 -0.582325 0.225703 -1.164569]" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# break it into pieces\n", "pieces = [df[:3], df[3:7], df[7:]]\n", "pieces" ] }, { "cell_type": "code", "execution_count": 91, "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", "
0123
01.0170960.583143-0.0295780.420775
1-1.3781940.443747-1.0566490.267996
20.6756360.288908-2.114351-1.957281
3-1.4943391.6225560.426388-1.876453
41.3488821.556022-0.490135-1.438133
5-1.830610-1.5033970.4983041.038869
60.246876-2.1754571.623862-0.734835
7-0.2370100.462616-0.6941090.914963
80.9613740.8451122.0627282.151655
90.324078-0.5823250.225703-1.164569
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.017096 0.583143 -0.029578 0.420775\n", "1 -1.378194 0.443747 -1.056649 0.267996\n", "2 0.675636 0.288908 -2.114351 -1.957281\n", "3 -1.494339 1.622556 0.426388 -1.876453\n", "4 1.348882 1.556022 -0.490135 -1.438133\n", "5 -1.830610 -1.503397 0.498304 1.038869\n", "6 0.246876 -2.175457 1.623862 -0.734835\n", "7 -0.237010 0.462616 -0.694109 0.914963\n", "8 0.961374 0.845112 2.062728 2.151655\n", "9 0.324078 -0.582325 0.225703 -1.164569" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat(pieces)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Join\n", "\n", "SQL style merges. See the [Database style joining](http://pandas.pydata.org/pandas-docs/stable/merging.html#merging-join)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [], "source": [ "left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [], "source": [ "right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})" ] }, { "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", "
keylval
0foo1
1foo2
\n", "
" ], "text/plain": [ " key lval\n", "0 foo 1\n", "1 foo 2" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "left" ] }, { "cell_type": "code", "execution_count": 95, "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", "
keyrval
0foo4
1foo5
\n", "
" ], "text/plain": [ " key rval\n", "0 foo 4\n", "1 foo 5" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "right" ] }, { "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", "
keylvalrval
0foo14
1foo15
2foo24
3foo25
\n", "
" ], "text/plain": [ " key lval rval\n", "0 foo 1 4\n", "1 foo 1 5\n", "2 foo 2 4\n", "3 foo 2 5" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.merge(left, right, on='key')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Append\n", "\n", "Append rows to a dataframe. See the [Appending](http://pandas.pydata.org/pandas-docs/stable/merging.html#merging-concatenation)" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])" ] }, { "cell_type": "code", "execution_count": 98, "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", "
ABCD
0-1.0189430.8307980.4458580.779527
1-1.0482130.1879730.746063-0.323631
20.2781280.237679-0.1351530.467364
3-0.0046100.476545-0.6398980.803674
4-1.814833-1.970398-1.0643080.609056
5-0.6724011.9745661.3904011.254933
6-1.041315-0.098163-1.7935830.626114
7-0.982286-0.001413-1.222559-0.837308
\n", "
" ], "text/plain": [ " A B C D\n", "0 -1.018943 0.830798 0.445858 0.779527\n", "1 -1.048213 0.187973 0.746063 -0.323631\n", "2 0.278128 0.237679 -0.135153 0.467364\n", "3 -0.004610 0.476545 -0.639898 0.803674\n", "4 -1.814833 -1.970398 -1.064308 0.609056\n", "5 -0.672401 1.974566 1.390401 1.254933\n", "6 -1.041315 -0.098163 -1.793583 0.626114\n", "7 -0.982286 -0.001413 -1.222559 -0.837308" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A -0.004610\n", "B 0.476545\n", "C -0.639898\n", "D 0.803674\n", "Name: 3, dtype: float64" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = df.iloc[3]\n", "s" ] }, { "cell_type": "code", "execution_count": 100, "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", "
ABCD
0-1.0189430.8307980.4458580.779527
1-1.0482130.1879730.746063-0.323631
20.2781280.237679-0.1351530.467364
3-0.0046100.476545-0.6398980.803674
4-1.814833-1.970398-1.0643080.609056
5-0.6724011.9745661.3904011.254933
6-1.041315-0.098163-1.7935830.626114
7-0.982286-0.001413-1.222559-0.837308
8-0.0046100.476545-0.6398980.803674
\n", "
" ], "text/plain": [ " A B C D\n", "0 -1.018943 0.830798 0.445858 0.779527\n", "1 -1.048213 0.187973 0.746063 -0.323631\n", "2 0.278128 0.237679 -0.135153 0.467364\n", "3 -0.004610 0.476545 -0.639898 0.803674\n", "4 -1.814833 -1.970398 -1.064308 0.609056\n", "5 -0.672401 1.974566 1.390401 1.254933\n", "6 -1.041315 -0.098163 -1.793583 0.626114\n", "7 -0.982286 -0.001413 -1.222559 -0.837308\n", "8 -0.004610 0.476545 -0.639898 0.803674" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.append(s, ignore_index=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Grouping\n", "\n", "By “group by” we are referring to a process involving one or more of the following steps\n", "\n", "* **Splitting** the data into groups based on some criteria\n", "* **Applying** a function to each group independently\n", "* **Combining** the results into a data structure\n", "\n", "See the [Grouping section](http://pandas.pydata.org/pandas-docs/stable/groupby.html#groupby)" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],\n", " 'B' : ['one', 'one', 'two', 'three','two', 'two', 'one', 'three'],\n", " 'C' : np.random.randn(8),\n", " 'D' : np.random.randn(8)})" ] }, { "cell_type": "code", "execution_count": 102, "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", "
CD
AB
barone-0.464087-1.485496
three-0.9718130.645862
two0.4977162.246094
fooone0.7042970.578579
one0.567852-0.004890
three-2.437398-0.067146
two1.418824-1.359379
two0.029065-1.510072
\n", "
" ], "text/plain": [ " C D\n", "A B \n", "bar one -0.464087 -1.485496\n", " three -0.971813 0.645862\n", " two 0.497716 2.246094\n", "foo one 0.704297 0.578579\n", " one 0.567852 -0.004890\n", " three -2.437398 -0.067146\n", " two 1.418824 -1.359379\n", " two 0.029065 -1.510072" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.set_index(['A', 'B']).sort_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Grouping and then applying a function sum to the resulting groups." ] }, { "cell_type": "code", "execution_count": 103, "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", "
CD
AB
barone-0.464087-1.485496
three-0.9718130.645862
two0.4977162.246094
fooone0.7042970.578579
three-2.437398-0.067146
two1.418824-1.359379
\n", "
" ], "text/plain": [ " C D\n", "A B \n", "bar one -0.464087 -1.485496\n", " three -0.971813 0.645862\n", " two 0.497716 2.246094\n", "foo one 0.704297 0.578579\n", " three -2.437398 -0.067146\n", " two 1.418824 -1.359379" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.groupby(['A', 'B']).max()" ] }, { "cell_type": "code", "execution_count": 104, "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", "
CD
A
bar-0.9381851.406460
foo0.282639-2.362907
\n", "
" ], "text/plain": [ " C D\n", "A \n", "bar -0.938185 1.406460\n", "foo 0.282639 -2.362907" ] }, "execution_count": 104, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.groupby('A').sum()" ] }, { "cell_type": "code", "execution_count": 105, "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", "
CD
AB
barone-0.464087-1.485496
three-0.9718130.645862
two0.4977162.246094
fooone1.2721490.573690
three-2.437398-0.067146
two1.447889-2.869450
\n", "
" ], "text/plain": [ " C D\n", "A B \n", "bar one -0.464087 -1.485496\n", " three -0.971813 0.645862\n", " two 0.497716 2.246094\n", "foo one 1.272149 0.573690\n", " three -2.437398 -0.067146\n", " two 1.447889 -2.869450" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.groupby(['A','B']).sum()" ] }, { "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CD
AB
barone-0.464087-1.485496
three-0.9718130.645862
two0.4977162.246094
fooone0.7042970.578579
one0.567852-0.004890
three-2.437398-0.067146
two1.418824-1.359379
two0.029065-1.510072
\n", "
" ], "text/plain": [ " C D\n", "A B \n", "bar one -0.464087 -1.485496\n", " three -0.971813 0.645862\n", " two 0.497716 2.246094\n", "foo one 0.704297 0.578579\n", " one 0.567852 -0.004890\n", " three -2.437398 -0.067146\n", " two 1.418824 -1.359379\n", " two 0.029065 -1.510072" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.set_index(['A', 'B']).sort_index()" ] }, { "cell_type": "code", "execution_count": 107, "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", "
CD
countmeanstdmin25%50%75%maxcountmeanstdmin25%50%75%max
AB
barone1.0-0.464087NaN-0.464087-0.464087-0.464087-0.464087-0.4640871.0-1.485496NaN-1.485496-1.485496-1.485496-1.485496-1.485496
three1.0-0.971813NaN-0.971813-0.971813-0.971813-0.971813-0.9718131.00.645862NaN0.6458620.6458620.6458620.6458620.645862
two1.00.497716NaN0.4977160.4977160.4977160.4977160.4977161.02.246094NaN2.2460942.2460942.2460942.2460942.246094
fooone2.00.6360740.0964810.5678520.6019630.6360740.6701860.7042972.00.2868450.412575-0.0048900.1409780.2868450.4327120.578579
three1.0-2.437398NaN-2.437398-2.437398-2.437398-2.437398-2.4373981.0-0.067146NaN-0.067146-0.067146-0.067146-0.067146-0.067146
two2.00.7239440.9827080.0290650.3765050.7239441.0713841.4188242.0-1.4347250.106556-1.510072-1.472399-1.434725-1.397052-1.359379
\n", "
" ], "text/plain": [ " C \\\n", " count mean std min 25% 50% 75% \n", "A B \n", "bar one 1.0 -0.464087 NaN -0.464087 -0.464087 -0.464087 -0.464087 \n", " three 1.0 -0.971813 NaN -0.971813 -0.971813 -0.971813 -0.971813 \n", " two 1.0 0.497716 NaN 0.497716 0.497716 0.497716 0.497716 \n", "foo one 2.0 0.636074 0.096481 0.567852 0.601963 0.636074 0.670186 \n", " three 1.0 -2.437398 NaN -2.437398 -2.437398 -2.437398 -2.437398 \n", " two 2.0 0.723944 0.982708 0.029065 0.376505 0.723944 1.071384 \n", "\n", " D \\\n", " max count mean std min 25% 50% \n", "A B \n", "bar one -0.464087 1.0 -1.485496 NaN -1.485496 -1.485496 -1.485496 \n", " three -0.971813 1.0 0.645862 NaN 0.645862 0.645862 0.645862 \n", " two 0.497716 1.0 2.246094 NaN 2.246094 2.246094 2.246094 \n", "foo one 0.704297 2.0 0.286845 0.412575 -0.004890 0.140978 0.286845 \n", " three -2.437398 1.0 -0.067146 NaN -0.067146 -0.067146 -0.067146 \n", " two 1.418824 2.0 -1.434725 0.106556 -1.510072 -1.472399 -1.434725 \n", "\n", " \n", " 75% max \n", "A B \n", "bar one -1.485496 -1.485496 \n", " three 0.645862 0.645862 \n", " two 2.246094 2.246094 \n", "foo one 0.432712 0.578579 \n", " three -0.067146 -0.067146 \n", " two -1.397052 -1.359379 " ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.groupby(['A', 'B']).describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pivot Tables\n", "\n", "See the section on [Pivot Tables](http://pandas.pydata.org/pandas-docs/stable/reshaping.html#reshaping-pivot)." ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,\n", " 'B' : ['A', 'B', 'C'] * 4,\n", " 'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,\n", " 'D' : np.random.randn(12),\n", " 'E' : np.random.randn(12)})" ] }, { "cell_type": "code", "execution_count": 116, "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", "
ABCDE
0oneAfoo-0.137884-0.216885
1oneBfoo0.4405090.560528
2twoCfoo0.5744340.242231
3threeAbar0.4188300.376244
4oneBbar-0.201552-0.109787
5oneCbar1.500469-0.669567
6twoAfoo-2.094960-0.861628
7threeBfoo-1.2368051.951345
8oneCfoo-0.1283130.729287
9oneAbar0.021624-0.664850
10twoBbar-0.0942071.854912
11threeCbar-0.017477-0.316258
\n", "
" ], "text/plain": [ " A B C D E\n", "0 one A foo -0.137884 -0.216885\n", "1 one B foo 0.440509 0.560528\n", "2 two C foo 0.574434 0.242231\n", "3 three A bar 0.418830 0.376244\n", "4 one B bar -0.201552 -0.109787\n", "5 one C bar 1.500469 -0.669567\n", "6 two A foo -2.094960 -0.861628\n", "7 three B foo -1.236805 1.951345\n", "8 one C foo -0.128313 0.729287\n", "9 one A bar 0.021624 -0.664850\n", "10 two B bar -0.094207 1.854912\n", "11 three C bar -0.017477 -0.316258" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can produce pivot tables from this data very easily:" ] }, { "cell_type": "code", "execution_count": 117, "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", "
Cbarfoo
AB
oneA0.021624-0.137884
B-0.2015520.440509
C1.500469-0.128313
threeA0.418830NaN
BNaN-1.236805
C-0.017477NaN
twoANaN-2.094960
B-0.094207NaN
CNaN0.574434
\n", "
" ], "text/plain": [ "C bar foo\n", "A B \n", "one A 0.021624 -0.137884\n", " B -0.201552 0.440509\n", " C 1.500469 -0.128313\n", "three A 0.418830 NaN\n", " B NaN -1.236805\n", " C -0.017477 NaN\n", "two A NaN -2.094960\n", " B -0.094207 NaN\n", " C NaN 0.574434" ] }, "execution_count": 117, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Time Series\n", "\n", "pandas has simple, powerful, and efficient functionality for performing resampling operations during frequency conversion (e.g., converting secondly data into 5-minutely data). This is extremely common in, but not limited to, financial applications. See the [Time Series section](http://pandas.pydata.org/pandas-docs/stable/timeseries.html#timeseries)" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DatetimeIndex(['2012-01-01 00:00:00', '2012-01-01 00:00:01',\n", " '2012-01-01 00:00:02', '2012-01-01 00:00:03',\n", " '2012-01-01 00:00:04'],\n", " dtype='datetime64[ns]', freq='S')" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rng = pd.date_range('1/1/2012', periods=100, freq='S')\n", "rng[:5]" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2012-01-01 00:00:00 127\n", "2012-01-01 00:00:01 19\n", "2012-01-01 00:00:02 347\n", "2012-01-01 00:00:03 42\n", "2012-01-01 00:00:04 20\n", "Freq: S, dtype: int64" ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)\n", "ts[:5]" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2012-01-01 00:00:00 14711\n", "2012-01-01 00:01:00 9784\n", "Freq: T, dtype: int64" ] }, "execution_count": 123, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ts.resample('1Min').sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Time zone representation" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ts = pd.Series(np.random.randn(len(rng)), rng)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ts_utc = ts.tz_localize('UTC')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts_utc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Convert to another time zone" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts_utc.tz_convert('US/Eastern')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Converting between time span representations" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "rng = pd.date_range('1/1/2012', periods=5, freq='M')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ts = pd.Series(np.random.randn(len(rng)), index=rng)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ps = ts.to_period()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ps" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ps.to_timestamp()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Converting between period and timestamp enables some convenient arithmetic functions to be used. In the following example, we convert a quarterly frequency with year ending in November to 9am of the end of the month following the quarter end:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "prng = pd.period_range('1990Q1', '2000Q4', freq='Q-NOV')\n", "prng" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts = pd.Series(np.random.randn(len(prng)), prng)\n", "ts" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ts.index = (prng.asfreq('M', 'e') + 1).asfreq('H', 's') + 9\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Categoricals" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since version 0.15, pandas can include categorical data in a DataFrame. For full docs, see the [categorical introduction](http://pandas.pydata.org/pandas-docs/stable/categorical.html#categorical) and the [API documentation](http://pandas.pydata.org/pandas-docs/stable/api.html#api-categorical)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df = pd.DataFrame({\"id\":[1,2,3,4,5,6], \"raw_grade\":['a', 'b', 'b', 'a', 'a', 'e']})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Convert the raw grades to a categorical data type." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df[\"grade\"] = df[\"raw_grade\"].astype(\"category\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df[\"grade\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Rename the categories to more meaningful names (assigning to Series.cat.categories is inplace!)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df[\"grade\"].cat.categories = [\"very good\", \"good\", \"very bad\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reorder the categories and simultaneously add the missing categories (methods under Series .cat return a new Series per default)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df[\"grade\"] = df[\"grade\"].cat.set_categories([\"very bad\", \"bad\", \"medium\", \"good\", \"very good\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df[\"grade\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sorting is per order in the categories, not lexical order." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.sort_values(by=\"grade\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Grouping by a categorical column shows also empty categories." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.groupby(\"grade\").size()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting\n", "[Plotting](http://pandas.pydata.org/pandas-docs/stable/visualization.html#visualization) docs." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "ts = ts.cumsum()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "ts.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On DataFrame, plot() is a convenience to plot all of the columns with labels:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,\n", " columns=['A', 'B', 'C', 'D'])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "df = df.cumsum()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.figure(); df.plot(); plt.legend(loc='best')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting Data In/Out" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### CSV\n", "[Writing to a csv file](http://pandas.pydata.org/pandas-docs/stable/io.html#io-store-in-csv)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df.to_csv('foo.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Reading from a csv file](http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-csv-table)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pd.read_csv('foo.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Reading large CSV files" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iterator = pd.read_csv('foo.csv', iterator=True, chunksize=3)\n", "iterator" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iterator.get_chunk()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### HDF5\n", "Reading and writing to [HDFStores](http://pandas.pydata.org/pandas-docs/stable/io.html#io-hdf5)\n", "\n", "Writing to a HDF5 Store" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df.to_hdf('foo.h5','df')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reading from a HDF5 Store" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pd.read_hdf('foo.h5','df')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Excel\n", "\n", "Reading and writing to [MS Excel](http://pandas.pydata.org/pandas-docs/stable/io.html#io-excel)\n", "\n", "Writing to an excel file" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df.to_excel('foo.xlsx', sheet_name='Sheet1')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reading from an excel file" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Gotchas\n", "If you are trying an operation and you see an exception like:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if pd.Series([False, True, False]):\n", " print(\"I was true\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See [Comparisons](http://pandas.pydata.org/pandas-docs/stable/basics.html#basics-compare) for an explanation and what to do.\n", "\n", "See [Gotchas](http://pandas.pydata.org/pandas-docs/stable/gotchas.html#gotchas) as well." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "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.7.6" } }, "nbformat": 4, "nbformat_minor": 1 }