{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Object creation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the [Data structure intro section](https://pandas.pydata.org/pandas-docs/stable/dsintro.html#dsintro).\n",
"\n",
"\n",
"Creating a [Series](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html#pandas.Series) by passing a list of values, letting pandas create a default integer index:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 1.0\n",
"1 3.0\n",
"2 5.0\n",
"3 NaN\n",
"4 6.0\n",
"5 8.0\n",
"dtype: float64"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = pd.Series([1,3,5,np.nan,6,8])\n",
"s"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can create `Series` from `numpy.array`."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 1\n",
"1 2\n",
"2 3\n",
"3 4\n",
"4 5\n",
"dtype: int64"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s1 = pd.Series(np.array([1,2,3,4,5]))\n",
"s1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Creating a [DataFrame](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html#pandas.DataFrame) by passing a NumPy array, with a `datetime` index and labeled columns:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',\n",
" '2018-01-05', '2018-01-06'],\n",
" dtype='datetime64[ns]', freq='D')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dates = pd.date_range('20180101', periods=6)\n",
"dates"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" 0.336841 \n",
" 0.302999 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 0.298659 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" 0.578785 \n",
" -0.649389 \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" -0.719793 \n",
" -1.199080 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-01 0.689197 -0.748328 0.336841 0.302999\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290\n",
"2018-01-04 -2.081735 0.503221 -0.748308 0.298659\n",
"2018-01-05 -0.189942 -0.059702 0.578785 -0.649389\n",
"2018-01-06 1.121153 1.116452 -0.719793 -1.199080"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))\n",
"df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Creating `DataFrame` from python `dict`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" E \n",
" F \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1.0 \n",
" 2013-01-02 \n",
" 1.0 \n",
" 3 \n",
" test \n",
" foo \n",
" \n",
" \n",
" 1 \n",
" 1.0 \n",
" 2013-01-02 \n",
" 1.0 \n",
" 3 \n",
" train \n",
" foo \n",
" \n",
" \n",
" 2 \n",
" 1.0 \n",
" 2013-01-02 \n",
" 1.0 \n",
" 3 \n",
" test \n",
" foo \n",
" \n",
" \n",
" 3 \n",
" 1.0 \n",
" 2013-01-02 \n",
" 1.0 \n",
" 3 \n",
" train \n",
" foo \n",
" \n",
" \n",
"
\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": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"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' })\n",
"df2"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A float64\n",
"B datetime64[s]\n",
"C float32\n",
"D int32\n",
"E category\n",
"F object\n",
"dtype: object"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2.dtypes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Viewing Data"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" 0.336841 \n",
" 0.302999 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 0.298659 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" 0.578785 \n",
" -0.649389 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-01 0.689197 -0.748328 0.336841 0.302999\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290\n",
"2018-01-04 -2.081735 0.503221 -0.748308 0.298659\n",
"2018-01-05 -0.189942 -0.059702 0.578785 -0.649389"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Display the `index`, columns, and the underlying `NumPy` data:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',\n",
" '2018-01-05', '2018-01-06'],\n",
" dtype='datetime64[ns]', freq='D')"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.index"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['A', 'B', 'C', 'D'], dtype='object')"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.columns"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0.68919679, -0.74832834, 0.33684064, 0.3029987 ],\n",
" [ 0.01173233, 1.80050913, -0.73033801, -0.59073464],\n",
" [-0.01327916, 1.47011302, -0.0476773 , -0.40828974],\n",
" [-2.08173485, 0.50322085, -0.7483085 , 0.2986594 ],\n",
" [-0.18994195, -0.05970245, 0.57878542, -0.64938875],\n",
" [ 1.12115282, 1.1164519 , -0.71979345, -1.19908042]])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.values"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some basic stats."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" count \n",
" 6.000000 \n",
" 6.000000 \n",
" 6.000000 \n",
" 6.000000 \n",
" \n",
" \n",
" mean \n",
" -0.077146 \n",
" 0.680377 \n",
" -0.221749 \n",
" -0.374306 \n",
" \n",
" \n",
" std \n",
" 1.101479 \n",
" 0.968384 \n",
" 0.594501 \n",
" 0.585755 \n",
" \n",
" \n",
" min \n",
" -2.081735 \n",
" -0.748328 \n",
" -0.748308 \n",
" -1.199080 \n",
" \n",
" \n",
" 25% \n",
" -0.145776 \n",
" 0.081028 \n",
" -0.727702 \n",
" -0.634725 \n",
" \n",
" \n",
" 50% \n",
" -0.000773 \n",
" 0.809836 \n",
" -0.383735 \n",
" -0.499512 \n",
" \n",
" \n",
" 75% \n",
" 0.519831 \n",
" 1.381698 \n",
" 0.240711 \n",
" 0.121922 \n",
" \n",
" \n",
" max \n",
" 1.121153 \n",
" 1.800509 \n",
" 0.578785 \n",
" 0.302999 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"count 6.000000 6.000000 6.000000 6.000000\n",
"mean -0.077146 0.680377 -0.221749 -0.374306\n",
"std 1.101479 0.968384 0.594501 0.585755\n",
"min -2.081735 -0.748328 -0.748308 -1.199080\n",
"25% -0.145776 0.081028 -0.727702 -0.634725\n",
"50% -0.000773 0.809836 -0.383735 -0.499512\n",
"75% 0.519831 1.381698 0.240711 0.121922\n",
"max 1.121153 1.800509 0.578785 0.302999"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.describe()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 2018-01-02 \n",
" 2018-01-03 \n",
" 2018-01-04 \n",
" 2018-01-05 \n",
" 2018-01-06 \n",
" \n",
" \n",
" \n",
" \n",
" A \n",
" 0.689197 \n",
" 0.011732 \n",
" -0.013279 \n",
" -2.081735 \n",
" -0.189942 \n",
" 1.121153 \n",
" \n",
" \n",
" B \n",
" -0.748328 \n",
" 1.800509 \n",
" 1.470113 \n",
" 0.503221 \n",
" -0.059702 \n",
" 1.116452 \n",
" \n",
" \n",
" C \n",
" 0.336841 \n",
" -0.730338 \n",
" -0.047677 \n",
" -0.748308 \n",
" 0.578785 \n",
" -0.719793 \n",
" \n",
" \n",
" D \n",
" 0.302999 \n",
" -0.590735 \n",
" -0.408290 \n",
" 0.298659 \n",
" -0.649389 \n",
" -1.199080 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 2018-01-01 2018-01-02 2018-01-03 2018-01-04 2018-01-05 2018-01-06\n",
"A 0.689197 0.011732 -0.013279 -2.081735 -0.189942 1.121153\n",
"B -0.748328 1.800509 1.470113 0.503221 -0.059702 1.116452\n",
"C 0.336841 -0.730338 -0.047677 -0.748308 0.578785 -0.719793\n",
"D 0.302999 -0.590735 -0.408290 0.298659 -0.649389 -1.199080"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.T"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" D \n",
" C \n",
" B \n",
" A \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.302999 \n",
" 0.336841 \n",
" -0.748328 \n",
" 0.689197 \n",
" \n",
" \n",
" 2018-01-02 \n",
" -0.590735 \n",
" -0.730338 \n",
" 1.800509 \n",
" 0.011732 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.408290 \n",
" -0.047677 \n",
" 1.470113 \n",
" -0.013279 \n",
" \n",
" \n",
" 2018-01-04 \n",
" 0.298659 \n",
" -0.748308 \n",
" 0.503221 \n",
" -2.081735 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.649389 \n",
" 0.578785 \n",
" -0.059702 \n",
" -0.189942 \n",
" \n",
" \n",
" 2018-01-06 \n",
" -1.199080 \n",
" -0.719793 \n",
" 1.116452 \n",
" 1.121153 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" D C B A\n",
"2018-01-01 0.302999 0.336841 -0.748328 0.689197\n",
"2018-01-02 -0.590735 -0.730338 1.800509 0.011732\n",
"2018-01-03 -0.408290 -0.047677 1.470113 -0.013279\n",
"2018-01-04 0.298659 -0.748308 0.503221 -2.081735\n",
"2018-01-05 -0.649389 0.578785 -0.059702 -0.189942\n",
"2018-01-06 -1.199080 -0.719793 1.116452 1.121153"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.sort_index(axis=1, ascending=False)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" 0.336841 \n",
" 0.302999 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" 0.578785 \n",
" -0.649389 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 0.298659 \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" -0.719793 \n",
" -1.199080 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-01 0.689197 -0.748328 0.336841 0.302999\n",
"2018-01-05 -0.189942 -0.059702 0.578785 -0.649389\n",
"2018-01-04 -2.081735 0.503221 -0.748308 0.298659\n",
"2018-01-06 1.121153 1.116452 -0.719793 -1.199080\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.sort_values(by='B')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Selection by label"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the indexing documentation [Indexing and Selecting Data](https://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing) and [MultiIndex / Advanced Indexing](https://pandas.pydata.org/pandas-docs/stable/advanced.html#advanced)."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2018-01-01 0.689197\n",
"2018-01-02 0.011732\n",
"2018-01-03 -0.013279\n",
"2018-01-04 -2.081735\n",
"2018-01-05 -0.189942\n",
"2018-01-06 1.121153\n",
"Freq: D, Name: A, dtype: float64"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df['A']"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" 0.336841 \n",
" 0.302999 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-01 0.689197 -0.748328 0.336841 0.302999\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[0:3]"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 0.298659 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290\n",
"2018-01-04 -2.081735 0.503221 -0.748308 0.298659"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df['20180102':'20180104']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Selection by label:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A 0.689197\n",
"B -0.748328\n",
"C 0.336841\n",
"D 0.302999\n",
"Name: 2018-01-01 00:00:00, dtype: float64"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.loc[dates[0]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Selecting on a multi-axis by label:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B\n",
"2018-01-01 0.689197 -0.748328\n",
"2018-01-02 0.011732 1.800509\n",
"2018-01-03 -0.013279 1.470113\n",
"2018-01-04 -2.081735 0.503221\n",
"2018-01-05 -0.189942 -0.059702\n",
"2018-01-06 1.121153 1.116452"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.loc[:,['A','B']]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Showing label slicing, both endpoints are **included**:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B\n",
"2018-01-02 0.011732 1.800509\n",
"2018-01-03 -0.013279 1.470113\n",
"2018-01-04 -2.081735 0.503221"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.loc['20180102':'20180104',['A','B']]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reduction in the dimensions of the returned object:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A 0.011732\n",
"B 1.800509\n",
"Name: 2018-01-02 00:00:00, dtype: float64"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.loc['20180102',['A','B']]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For getting a scalar value:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.6891967902179298"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.loc[dates[0],'A']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For getting fast access to a scalar (equivalent to the prior method):"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.6891967902179298"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.at[dates[0],'A']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note**\n",
"\n",
"While standard Python / Numpy expressions for selecting and setting are intuitive and come in handy for interactive work, for production code, use the optimized pandas data access methods, `.at`, `.iat`, `.loc` and `.iloc`. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Selection by position"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A -2.081735\n",
"B 0.503221\n",
"C -0.748308\n",
"D 0.298659\n",
"Name: 2018-01-04 00:00:00, dtype: float64"
]
},
"execution_count": 25,
"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": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B\n",
"2018-01-04 -2.081735 0.503221\n",
"2018-01-05 -0.189942 -0.059702"
]
},
"execution_count": 26,
"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": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" C \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" -0.730338 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" -0.047677 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" 0.578785 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A C\n",
"2018-01-02 0.011732 -0.730338\n",
"2018-01-03 -0.013279 -0.047677\n",
"2018-01-05 -0.189942 0.578785"
]
},
"execution_count": 27,
"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": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.iloc[1:3,:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For slicing columns explicitly:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" B \n",
" C \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" -0.748328 \n",
" 0.336841 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 1.800509 \n",
" -0.730338 \n",
" \n",
" \n",
" 2018-01-03 \n",
" 1.470113 \n",
" -0.047677 \n",
" \n",
" \n",
" 2018-01-04 \n",
" 0.503221 \n",
" -0.748308 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.059702 \n",
" 0.578785 \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.116452 \n",
" -0.719793 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" B C\n",
"2018-01-01 -0.748328 0.336841\n",
"2018-01-02 1.800509 -0.730338\n",
"2018-01-03 1.470113 -0.047677\n",
"2018-01-04 0.503221 -0.748308\n",
"2018-01-05 -0.059702 0.578785\n",
"2018-01-06 1.116452 -0.719793"
]
},
"execution_count": 29,
"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": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.8005091253933956"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.iloc[1,1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For getting fast access to a scalar (equivalent to the prior method):"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.8005091253933956"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.iat[1,1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Boolean indexing"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" 0.336841 \n",
" 0.302999 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" -0.719793 \n",
" -1.199080 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-01 0.689197 -0.748328 0.336841 0.302999\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735\n",
"2018-01-06 1.121153 1.116452 -0.719793 -1.199080"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[df.A > 0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Selecting values from a DataFrame where a boolean condition is met."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" NaN \n",
" 0.336841 \n",
" 0.302999 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" NaN \n",
" NaN \n",
" \n",
" \n",
" 2018-01-03 \n",
" NaN \n",
" 1.470113 \n",
" NaN \n",
" NaN \n",
" \n",
" \n",
" 2018-01-04 \n",
" NaN \n",
" 0.503221 \n",
" NaN \n",
" 0.298659 \n",
" \n",
" \n",
" 2018-01-05 \n",
" NaN \n",
" NaN \n",
" 0.578785 \n",
" NaN \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" NaN \n",
" NaN \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"2018-01-01 0.689197 NaN 0.336841 0.302999\n",
"2018-01-02 0.011732 1.800509 NaN NaN\n",
"2018-01-03 NaN 1.470113 NaN NaN\n",
"2018-01-04 NaN 0.503221 NaN 0.298659\n",
"2018-01-05 NaN NaN 0.578785 NaN\n",
"2018-01-06 1.121153 1.116452 NaN NaN"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[df > 0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the [isin()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.isin.html#pandas.Series.isin) method for filtering:"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" E \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.689197 \n",
" -0.748328 \n",
" 0.336841 \n",
" 0.302999 \n",
" one \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" -0.590735 \n",
" one \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" two \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 0.298659 \n",
" three \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" 0.578785 \n",
" -0.649389 \n",
" four \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" -0.719793 \n",
" -1.199080 \n",
" three \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D E\n",
"2018-01-01 0.689197 -0.748328 0.336841 0.302999 one\n",
"2018-01-02 0.011732 1.800509 -0.730338 -0.590735 one\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290 two\n",
"2018-01-04 -2.081735 0.503221 -0.748308 0.298659 three\n",
"2018-01-05 -0.189942 -0.059702 0.578785 -0.649389 four\n",
"2018-01-06 1.121153 1.116452 -0.719793 -1.199080 three"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2 = df.copy()\n",
"df2['E'] = ['one', 'one','two','three','four','three']\n",
"df2"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" E \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" -0.408290 \n",
" two \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" 0.578785 \n",
" -0.649389 \n",
" four \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D E\n",
"2018-01-03 -0.013279 1.470113 -0.047677 -0.408290 two\n",
"2018-01-05 -0.189942 -0.059702 0.578785 -0.649389 four"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2[df2['E'].isin(['two','four'])]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Setting\n",
"\n",
"Setting a new column automatically aligns the data by the indexes."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2018-01-02 1\n",
"2018-01-03 2\n",
"2018-01-04 3\n",
"2018-01-05 4\n",
"2018-01-06 5\n",
"2018-01-07 6\n",
"Freq: D, dtype: int64"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20180102', periods=6))\n",
"s1"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [],
"source": [
"df['F'] = s1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Setting values by label:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [],
"source": [
"df.at[dates[0],'A'] = 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Setting values by position:"
]
},
{
"cell_type": "code",
"execution_count": 39,
"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": 40,
"metadata": {},
"outputs": [],
"source": [
"df.loc[:,'D'] = np.array([5] * len(df))"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.000000 \n",
" 0.000000 \n",
" 0.336841 \n",
" 5.0 \n",
" NaN \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" 5.0 \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" 5.0 \n",
" 2.0 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 5.0 \n",
" 3.0 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" 0.578785 \n",
" 5.0 \n",
" 4.0 \n",
" \n",
" \n",
" 2018-01-06 \n",
" 1.121153 \n",
" 1.116452 \n",
" -0.719793 \n",
" 5.0 \n",
" 5.0 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F\n",
"2018-01-01 0.000000 0.000000 0.336841 5.0 NaN\n",
"2018-01-02 0.011732 1.800509 -0.730338 5.0 1.0\n",
"2018-01-03 -0.013279 1.470113 -0.047677 5.0 2.0\n",
"2018-01-04 -2.081735 0.503221 -0.748308 5.0 3.0\n",
"2018-01-05 -0.189942 -0.059702 0.578785 5.0 4.0\n",
"2018-01-06 1.121153 1.116452 -0.719793 5.0 5.0"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A `where` operation with setting."
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.000000 \n",
" 0.000000 \n",
" -0.336841 \n",
" -5.0 \n",
" NaN \n",
" \n",
" \n",
" 2018-01-02 \n",
" -0.011732 \n",
" -1.800509 \n",
" -0.730338 \n",
" -5.0 \n",
" -1.0 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" -1.470113 \n",
" -0.047677 \n",
" -5.0 \n",
" -2.0 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" -0.503221 \n",
" -0.748308 \n",
" -5.0 \n",
" -3.0 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -0.189942 \n",
" -0.059702 \n",
" -0.578785 \n",
" -5.0 \n",
" -4.0 \n",
" \n",
" \n",
" 2018-01-06 \n",
" -1.121153 \n",
" -1.116452 \n",
" -0.719793 \n",
" -5.0 \n",
" -5.0 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F\n",
"2018-01-01 0.000000 0.000000 -0.336841 -5.0 NaN\n",
"2018-01-02 -0.011732 -1.800509 -0.730338 -5.0 -1.0\n",
"2018-01-03 -0.013279 -1.470113 -0.047677 -5.0 -2.0\n",
"2018-01-04 -2.081735 -0.503221 -0.748308 -5.0 -3.0\n",
"2018-01-05 -0.189942 -0.059702 -0.578785 -5.0 -4.0\n",
"2018-01-06 -1.121153 -1.116452 -0.719793 -5.0 -5.0"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2 = df.copy()\n",
"df2[df2 > 0] = -df2\n",
"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](https://pandas.pydata.org/pandas-docs/stable/missing_data.html#missing-data) section.\n",
"\n",
"Reindexing allows you to change/add/delete the index on a specified axis. This returns a copy of the dat"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" E \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.000000 \n",
" 0.000000 \n",
" 0.336841 \n",
" 5.0 \n",
" NaN \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" 5.0 \n",
" 1.0 \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" 5.0 \n",
" 2.0 \n",
" NaN \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 5.0 \n",
" 3.0 \n",
" NaN \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F E\n",
"2018-01-01 0.000000 0.000000 0.336841 5.0 NaN 1.0\n",
"2018-01-02 0.011732 1.800509 -0.730338 5.0 1.0 1.0\n",
"2018-01-03 -0.013279 1.470113 -0.047677 5.0 2.0 NaN\n",
"2018-01-04 -2.081735 0.503221 -0.748308 5.0 3.0 NaN"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])\n",
"df1.loc[dates[0]:dates[1],'E'] = 1\n",
"df1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To drop `any` rows that have missing data."
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" E \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" 5.0 \n",
" 1.0 \n",
" 1.0 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F E\n",
"2018-01-02 0.011732 1.800509 -0.730338 5.0 1.0 1.0"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df1.dropna(how='any')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Filling missing data"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" E \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.000000 \n",
" 0.000000 \n",
" 0.336841 \n",
" 5.0 \n",
" 5.0 \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.730338 \n",
" 5.0 \n",
" 1.0 \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.013279 \n",
" 1.470113 \n",
" -0.047677 \n",
" 5.0 \n",
" 2.0 \n",
" 5.0 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.081735 \n",
" 0.503221 \n",
" -0.748308 \n",
" 5.0 \n",
" 3.0 \n",
" 5.0 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F E\n",
"2018-01-01 0.000000 0.000000 0.336841 5.0 5.0 1.0\n",
"2018-01-02 0.011732 1.800509 -0.730338 5.0 1.0 1.0\n",
"2018-01-03 -0.013279 1.470113 -0.047677 5.0 2.0 5.0\n",
"2018-01-04 -2.081735 0.503221 -0.748308 5.0 3.0 5.0"
]
},
"execution_count": 45,
"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": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" E \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" False \n",
" False \n",
" False \n",
" False \n",
" True \n",
" False \n",
" \n",
" \n",
" 2018-01-02 \n",
" False \n",
" False \n",
" False \n",
" False \n",
" False \n",
" False \n",
" \n",
" \n",
" 2018-01-03 \n",
" False \n",
" False \n",
" False \n",
" False \n",
" False \n",
" True \n",
" \n",
" \n",
" 2018-01-04 \n",
" False \n",
" False \n",
" False \n",
" False \n",
" False \n",
" True \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F E\n",
"2018-01-01 False False False False True False\n",
"2018-01-02 False False False False False False\n",
"2018-01-03 False False False False False True\n",
"2018-01-04 False False False False False True"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.isna(df1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Operations\n",
"\n",
"Operations in general exclude missing data."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A -0.192012\n",
"B 0.805099\n",
"C -0.221749\n",
"D 5.000000\n",
"F 3.000000\n",
"dtype: float64"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.mean()"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2018-01-01 1.334210\n",
"2018-01-02 1.416381\n",
"2018-01-03 1.681831\n",
"2018-01-04 1.134636\n",
"2018-01-05 1.865828\n",
"2018-01-06 2.303562\n",
"Freq: D, dtype: float64"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.mean(1) # other axis"
]
},
{
"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": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2018-01-01 NaN\n",
"2018-01-02 NaN\n",
"2018-01-03 1.0\n",
"2018-01-04 3.0\n",
"2018-01-05 5.0\n",
"2018-01-06 NaN\n",
"Freq: D, dtype: float64"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = pd.Series([1,3,5,np.nan,6,8], index=dates).shift(2)\n",
"s"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" NaN \n",
" NaN \n",
" NaN \n",
" NaN \n",
" NaN \n",
" \n",
" \n",
" 2018-01-02 \n",
" NaN \n",
" NaN \n",
" NaN \n",
" NaN \n",
" NaN \n",
" \n",
" \n",
" 2018-01-03 \n",
" -1.013279 \n",
" 0.470113 \n",
" -1.047677 \n",
" 4.0 \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -5.081735 \n",
" -2.496779 \n",
" -3.748308 \n",
" 2.0 \n",
" 0.0 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -5.189942 \n",
" -5.059702 \n",
" -4.421215 \n",
" 0.0 \n",
" -1.0 \n",
" \n",
" \n",
" 2018-01-06 \n",
" NaN \n",
" NaN \n",
" NaN \n",
" NaN \n",
" NaN \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F\n",
"2018-01-01 NaN NaN NaN NaN NaN\n",
"2018-01-02 NaN NaN NaN NaN NaN\n",
"2018-01-03 -1.013279 0.470113 -1.047677 4.0 1.0\n",
"2018-01-04 -5.081735 -2.496779 -3.748308 2.0 0.0\n",
"2018-01-05 -5.189942 -5.059702 -4.421215 0.0 -1.0\n",
"2018-01-06 NaN NaN NaN NaN NaN"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.sub(s, axis='index')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Applying functions to the data:"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" F \n",
" \n",
" \n",
" \n",
" \n",
" 2018-01-01 \n",
" 0.000000 \n",
" 0.000000 \n",
" 0.336841 \n",
" 5.0 \n",
" NaN \n",
" \n",
" \n",
" 2018-01-02 \n",
" 0.011732 \n",
" 1.800509 \n",
" -0.393497 \n",
" 10.0 \n",
" 1.0 \n",
" \n",
" \n",
" 2018-01-03 \n",
" -0.001547 \n",
" 3.270622 \n",
" -0.441175 \n",
" 15.0 \n",
" 3.0 \n",
" \n",
" \n",
" 2018-01-04 \n",
" -2.083282 \n",
" 3.773843 \n",
" -1.189483 \n",
" 20.0 \n",
" 6.0 \n",
" \n",
" \n",
" 2018-01-05 \n",
" -2.273224 \n",
" 3.714141 \n",
" -0.610698 \n",
" 25.0 \n",
" 10.0 \n",
" \n",
" \n",
" 2018-01-06 \n",
" -1.152071 \n",
" 4.830592 \n",
" -1.330491 \n",
" 30.0 \n",
" 15.0 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D F\n",
"2018-01-01 0.000000 0.000000 0.336841 5.0 NaN\n",
"2018-01-02 0.011732 1.800509 -0.393497 10.0 1.0\n",
"2018-01-03 -0.001547 3.270622 -0.441175 15.0 3.0\n",
"2018-01-04 -2.083282 3.773843 -1.189483 20.0 6.0\n",
"2018-01-05 -2.273224 3.714141 -0.610698 25.0 10.0\n",
"2018-01-06 -1.152071 4.830592 -1.330491 30.0 15.0"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.apply(np.cumsum)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A 3.202888\n",
"B 1.860212\n",
"C 1.327094\n",
"D 0.000000\n",
"F 4.000000\n",
"dtype: float64"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.apply(lambda x: x.max() - x.min())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Histogramming"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 0\n",
"1 6\n",
"2 4\n",
"3 0\n",
"4 2\n",
"5 5\n",
"6 1\n",
"7 0\n",
"8 2\n",
"9 1\n",
"dtype: int64"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = pd.Series(np.random.randint(0, 7, size=10))\n",
"s"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 3\n",
"2 2\n",
"1 2\n",
"6 1\n",
"4 1\n",
"5 1\n",
"Name: count, dtype: int64"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s.value_counts()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### String methods"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`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/3/library/re.html) by default (and in some cases always uses them)."
]
},
{
"cell_type": "code",
"execution_count": 55,
"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": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])\n",
"s"
]
},
{
"cell_type": "code",
"execution_count": 56,
"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": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s.str.lower()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Merge\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](https://pandas.pydata.org/pandas-docs/stable/merging.html#merging) section."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Concat"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" 0 \n",
" 1 \n",
" 2 \n",
" 3 \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1.196264 \n",
" -0.307483 \n",
" 1.087363 \n",
" -0.063503 \n",
" \n",
" \n",
" 1 \n",
" -0.553211 \n",
" -0.744502 \n",
" -0.109022 \n",
" -0.271307 \n",
" \n",
" \n",
" 2 \n",
" -3.251581 \n",
" 1.197394 \n",
" 1.508955 \n",
" 1.039690 \n",
" \n",
" \n",
" 3 \n",
" 1.536642 \n",
" 0.626617 \n",
" -1.684411 \n",
" -1.331959 \n",
" \n",
" \n",
" 4 \n",
" 0.678949 \n",
" -0.959102 \n",
" 0.707512 \n",
" -0.846799 \n",
" \n",
" \n",
" 5 \n",
" -1.748012 \n",
" -0.868352 \n",
" -1.068672 \n",
" 0.518735 \n",
" \n",
" \n",
" 6 \n",
" 0.933116 \n",
" 1.235156 \n",
" -0.356329 \n",
" -0.616035 \n",
" \n",
" \n",
" 7 \n",
" 0.442595 \n",
" 0.995129 \n",
" -0.609787 \n",
" 0.018593 \n",
" \n",
" \n",
" 8 \n",
" 0.673083 \n",
" -1.811854 \n",
" -0.780173 \n",
" 2.672571 \n",
" \n",
" \n",
" 9 \n",
" -1.125609 \n",
" 1.173348 \n",
" -0.377945 \n",
" -0.285722 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2 3\n",
"0 1.196264 -0.307483 1.087363 -0.063503\n",
"1 -0.553211 -0.744502 -0.109022 -0.271307\n",
"2 -3.251581 1.197394 1.508955 1.039690\n",
"3 1.536642 0.626617 -1.684411 -1.331959\n",
"4 0.678949 -0.959102 0.707512 -0.846799\n",
"5 -1.748012 -0.868352 -1.068672 0.518735\n",
"6 0.933116 1.235156 -0.356329 -0.616035\n",
"7 0.442595 0.995129 -0.609787 0.018593\n",
"8 0.673083 -1.811854 -0.780173 2.672571\n",
"9 -1.125609 1.173348 -0.377945 -0.285722"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.DataFrame(np.random.randn(10, 4))\n",
"df"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" 0 \n",
" 1 \n",
" 2 \n",
" 3 \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1.196264 \n",
" -0.307483 \n",
" 1.087363 \n",
" -0.063503 \n",
" \n",
" \n",
" 1 \n",
" -0.553211 \n",
" -0.744502 \n",
" -0.109022 \n",
" -0.271307 \n",
" \n",
" \n",
" 2 \n",
" -3.251581 \n",
" 1.197394 \n",
" 1.508955 \n",
" 1.039690 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2 3\n",
"0 1.196264 -0.307483 1.087363 -0.063503\n",
"1 -0.553211 -0.744502 -0.109022 -0.271307\n",
"2 -3.251581 1.197394 1.508955 1.039690"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pieces = [df[:3], df[3:7], df[7:]]\n",
"pieces[0]"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" 0 \n",
" 1 \n",
" 2 \n",
" 3 \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 1.196264 \n",
" -0.307483 \n",
" 1.087363 \n",
" -0.063503 \n",
" \n",
" \n",
" 1 \n",
" -0.553211 \n",
" -0.744502 \n",
" -0.109022 \n",
" -0.271307 \n",
" \n",
" \n",
" 2 \n",
" -3.251581 \n",
" 1.197394 \n",
" 1.508955 \n",
" 1.039690 \n",
" \n",
" \n",
" 3 \n",
" 1.536642 \n",
" 0.626617 \n",
" -1.684411 \n",
" -1.331959 \n",
" \n",
" \n",
" 4 \n",
" 0.678949 \n",
" -0.959102 \n",
" 0.707512 \n",
" -0.846799 \n",
" \n",
" \n",
" 5 \n",
" -1.748012 \n",
" -0.868352 \n",
" -1.068672 \n",
" 0.518735 \n",
" \n",
" \n",
" 6 \n",
" 0.933116 \n",
" 1.235156 \n",
" -0.356329 \n",
" -0.616035 \n",
" \n",
" \n",
" 7 \n",
" 0.442595 \n",
" 0.995129 \n",
" -0.609787 \n",
" 0.018593 \n",
" \n",
" \n",
" 8 \n",
" 0.673083 \n",
" -1.811854 \n",
" -0.780173 \n",
" 2.672571 \n",
" \n",
" \n",
" 9 \n",
" -1.125609 \n",
" 1.173348 \n",
" -0.377945 \n",
" -0.285722 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2 3\n",
"0 1.196264 -0.307483 1.087363 -0.063503\n",
"1 -0.553211 -0.744502 -0.109022 -0.271307\n",
"2 -3.251581 1.197394 1.508955 1.039690\n",
"3 1.536642 0.626617 -1.684411 -1.331959\n",
"4 0.678949 -0.959102 0.707512 -0.846799\n",
"5 -1.748012 -0.868352 -1.068672 0.518735\n",
"6 0.933116 1.235156 -0.356329 -0.616035\n",
"7 0.442595 0.995129 -0.609787 0.018593\n",
"8 0.673083 -1.811854 -0.780173 2.672571\n",
"9 -1.125609 1.173348 -0.377945 -0.285722"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.concat(pieces)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Join"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" key \n",
" lval \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" foo \n",
" 1 \n",
" \n",
" \n",
" 1 \n",
" foo \n",
" 2 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" key lval\n",
"0 foo 1\n",
"1 foo 2"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})\n",
"left"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" key \n",
" rval \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" foo \n",
" 4 \n",
" \n",
" \n",
" 1 \n",
" foo \n",
" 5 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" key rval\n",
"0 foo 4\n",
"1 foo 5"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})\n",
"right"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" key \n",
" lval \n",
" rval \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" foo \n",
" 1 \n",
" 4 \n",
" \n",
" \n",
" 1 \n",
" foo \n",
" 1 \n",
" 5 \n",
" \n",
" \n",
" 2 \n",
" foo \n",
" 2 \n",
" 4 \n",
" \n",
" \n",
" 3 \n",
" foo \n",
" 2 \n",
" 5 \n",
" \n",
" \n",
"
\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": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.merge(left, right, on='key')"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" key \n",
" lval \n",
" rval \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" foo \n",
" 1 \n",
" 4 \n",
" \n",
" \n",
" 1 \n",
" bar \n",
" 2 \n",
" 5 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" key lval rval\n",
"0 foo 1 4\n",
"1 bar 2 5"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]})\n",
"right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})\n",
"pd.merge(left, right, on='key')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Grouping\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",
"Read the [docs](https://pandas.pydata.org/pandas-docs/stable/groupby.html#groupby)."
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" foo \n",
" one \n",
" -1.784887 \n",
" 0.832337 \n",
" \n",
" \n",
" 1 \n",
" bar \n",
" one \n",
" 0.781068 \n",
" -1.339679 \n",
" \n",
" \n",
" 2 \n",
" foo \n",
" two \n",
" 0.078568 \n",
" 0.707609 \n",
" \n",
" \n",
" 3 \n",
" bar \n",
" three \n",
" -0.688408 \n",
" 0.432818 \n",
" \n",
" \n",
" 4 \n",
" foo \n",
" two \n",
" -1.895856 \n",
" 1.681678 \n",
" \n",
" \n",
" 5 \n",
" bar \n",
" two \n",
" 0.460244 \n",
" -1.310075 \n",
" \n",
" \n",
" 6 \n",
" foo \n",
" one \n",
" -0.800081 \n",
" -0.253487 \n",
" \n",
" \n",
" 7 \n",
" foo \n",
" three \n",
" -0.869920 \n",
" -1.378880 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B C D\n",
"0 foo one -1.784887 0.832337\n",
"1 bar one 0.781068 -1.339679\n",
"2 foo two 0.078568 0.707609\n",
"3 bar three -0.688408 0.432818\n",
"4 foo two -1.895856 1.681678\n",
"5 bar two 0.460244 -1.310075\n",
"6 foo one -0.800081 -0.253487\n",
"7 foo three -0.869920 -1.378880"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"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)})\n",
"df"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" A \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" bar \n",
" onethreetwo \n",
" 0.552903 \n",
" -2.216936 \n",
" \n",
" \n",
" foo \n",
" onetwotwoonethree \n",
" -5.272176 \n",
" 1.589256 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" B C D\n",
"A \n",
"bar onethreetwo 0.552903 -2.216936\n",
"foo onetwotwoonethree -5.272176 1.589256"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.groupby('A').sum()"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" \n",
" C \n",
" D \n",
" \n",
" \n",
" A \n",
" B \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" bar \n",
" one \n",
" 0.781068 \n",
" -1.339679 \n",
" \n",
" \n",
" three \n",
" -0.688408 \n",
" 0.432818 \n",
" \n",
" \n",
" two \n",
" 0.460244 \n",
" -1.310075 \n",
" \n",
" \n",
" foo \n",
" one \n",
" -2.584968 \n",
" 0.578849 \n",
" \n",
" \n",
" three \n",
" -0.869920 \n",
" -1.378880 \n",
" \n",
" \n",
" two \n",
" -1.817288 \n",
" 2.389287 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" C D\n",
"A B \n",
"bar one 0.781068 -1.339679\n",
" three -0.688408 0.432818\n",
" two 0.460244 -1.310075\n",
"foo one -2.584968 0.578849\n",
" three -0.869920 -1.378880\n",
" two -1.817288 2.389287"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.groupby(['A','B']).sum()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Reshaping\n",
"\n",
"Read the docs [here](https://pandas.pydata.org/pandas-docs/stable/advanced.html#advanced-hierarchical) and [here](https://pandas.pydata.org/pandas-docs/stable/reshaping.html#reshaping-stacking)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Stack\n"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[('bar', 'one'),\n",
" ('bar', 'two'),\n",
" ('baz', 'one'),\n",
" ('baz', 'two'),\n",
" ('foo', 'one'),\n",
" ('foo', 'two'),\n",
" ('qux', 'one'),\n",
" ('qux', 'two')]"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tuples = list(zip(*[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],\n",
" ['one', 'two', 'one', 'two','one', 'two', 'one', 'two']]))\n",
"tuples"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [],
"source": [
"df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])\n"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [],
"source": [
"df2 = df[:4]"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" \n",
" \n",
" first \n",
" second \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" bar \n",
" one \n",
" 1.202213 \n",
" -0.969292 \n",
" \n",
" \n",
" two \n",
" 1.398283 \n",
" -0.909918 \n",
" \n",
" \n",
" baz \n",
" one \n",
" 0.149835 \n",
" -1.197965 \n",
" \n",
" \n",
" two \n",
" 0.262480 \n",
" 0.077155 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B\n",
"first second \n",
"bar one 1.202213 -0.969292\n",
" two 1.398283 -0.909918\n",
"baz one 0.149835 -1.197965\n",
" two 0.262480 0.077155"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The [stack()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.stack.html#pandas.DataFrame.stack) method “compresses” a level in the DataFrame’s columns."
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"first second \n",
"bar one A 1.202213\n",
" B -0.969292\n",
" two A 1.398283\n",
" B -0.909918\n",
"baz one A 0.149835\n",
" B -1.197965\n",
" two A 0.262480\n",
" B 0.077155\n",
"dtype: float64"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stacked = df2.stack()\n",
"stacked"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With a “stacked” DataFrame or Series (having a MultiIndex as the index), the inverse operation of `stack()` is [unstack()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.unstack.html#pandas.DataFrame.unstack), which by default unstacks the last level:"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" \n",
" A \n",
" B \n",
" \n",
" \n",
" first \n",
" second \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" bar \n",
" one \n",
" 1.202213 \n",
" -0.969292 \n",
" \n",
" \n",
" two \n",
" 1.398283 \n",
" -0.909918 \n",
" \n",
" \n",
" baz \n",
" one \n",
" 0.149835 \n",
" -1.197965 \n",
" \n",
" \n",
" two \n",
" 0.262480 \n",
" 0.077155 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" A B\n",
"first second \n",
"bar one 1.202213 -0.969292\n",
" two 1.398283 -0.909918\n",
"baz one 0.149835 -1.197965\n",
" two 0.262480 0.077155"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stacked.unstack()"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" second \n",
" one \n",
" two \n",
" \n",
" \n",
" first \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" bar \n",
" A \n",
" 1.202213 \n",
" 1.398283 \n",
" \n",
" \n",
" B \n",
" -0.969292 \n",
" -0.909918 \n",
" \n",
" \n",
" baz \n",
" A \n",
" 0.149835 \n",
" 0.262480 \n",
" \n",
" \n",
" B \n",
" -1.197965 \n",
" 0.077155 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
"second one two\n",
"first \n",
"bar A 1.202213 1.398283\n",
" B -0.969292 -0.909918\n",
"baz A 0.149835 0.262480\n",
" B -1.197965 0.077155"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stacked.unstack(1)"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" first \n",
" bar \n",
" baz \n",
" \n",
" \n",
" second \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" one \n",
" A \n",
" 1.202213 \n",
" 0.149835 \n",
" \n",
" \n",
" B \n",
" -0.969292 \n",
" -1.197965 \n",
" \n",
" \n",
" two \n",
" A \n",
" 1.398283 \n",
" 0.262480 \n",
" \n",
" \n",
" B \n",
" -0.909918 \n",
" 0.077155 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
"first bar baz\n",
"second \n",
"one A 1.202213 0.149835\n",
" B -0.969292 -1.197965\n",
"two A 1.398283 0.262480\n",
" B -0.909918 0.077155"
]
},
"execution_count": 75,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stacked.unstack(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Time Series\n",
"\n",
"Read the [docs](https://pandas.pydata.org/pandas-docs/stable/timeseries.html#timeseries)"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/folders/b3/cjvms6c10k77tgv6k_rw3jbh0000gn/T/ipykernel_27636/3177683689.py:1: FutureWarning: 'S' is deprecated and will be removed in a future version, please use 's' instead.\n",
" rng = pd.date_range('1/1/2018', periods=100, freq='S')\n"
]
},
{
"data": {
"text/plain": [
"2018-01-01 26900\n",
"Freq: 5min, dtype: int64"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rng = pd.date_range('1/1/2018', periods=100, freq='S')\n",
"ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)\n",
"ts.resample('5Min').sum()"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2012-03-06 0.471622\n",
"2012-03-07 -1.126055\n",
"2012-03-08 -1.772563\n",
"2012-03-09 0.478307\n",
"2012-03-10 0.099097\n",
"Freq: D, dtype: float64"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')\n",
"ts = pd.Series(np.random.randn(len(rng)), rng)\n",
"ts"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/folders/b3/cjvms6c10k77tgv6k_rw3jbh0000gn/T/ipykernel_27636/3446765465.py:1: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead.\n",
" rng = pd.date_range('1/1/2012', periods=5, freq='M')\n"
]
},
{
"data": {
"text/plain": [
"2012-01-31 0.038780\n",
"2012-02-29 -0.192911\n",
"2012-03-31 1.175681\n",
"2012-04-30 0.970227\n",
"2012-05-31 0.545653\n",
"Freq: ME, dtype: float64"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rng = pd.date_range('1/1/2012', periods=5, freq='M')\n",
"ts = pd.Series(np.random.randn(len(rng)), index=rng)\n",
"ts"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2012-01 0.038780\n",
"2012-02 -0.192911\n",
"2012-03 1.175681\n",
"2012-04 0.970227\n",
"2012-05 0.545653\n",
"Freq: M, dtype: float64"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ps = ts.to_period()\n",
"ps"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2012-01-01 0.038780\n",
"2012-02-01 -0.192911\n",
"2012-03-01 1.175681\n",
"2012-04-01 0.970227\n",
"2012-05-01 0.545653\n",
"Freq: MS, dtype: float64"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ps.to_timestamp()"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAEECAYAAADNv0QiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAAsTAAALEwEAmpwYAAA+7klEQVR4nO3dd3xb1d348c+xZMl7O44TO3uRnWDCCCPMMJ6yShltn6aFlu7xtD8odDx9aKHwlJY+HbQlQFvoAjootKywE0iAJBAyyHacxBneQ7ItWZLP7497dS15x9ay/H2/XnlFuvfq6jrX+eronO/5HqW1RgghRHJKifcFCCGEiB4J8kIIkcQkyAshRBKTIC+EEElMgrwQQiQxCfJCCJHE7PG+gFBFRUV6ypQp8b4MIYQYVTZv3lyvtS7ua19CBfkpU6awadOmeF+GEEKMKkqpg/3tk+4aIYRIYhLkhRAiiUmQF0KIJCZBXgghkpgEeSGESGIS5IUQIolJkBdCiCgLdGm6uuJT1l2CvBBCRNn0bz3LtG89S3VTe8zfW4K8EELEyINrK2P+nhGZ8aqUqgJcQADwa60rlFIFwOPAFKAKuFZr3RSJ9xNCiNHC4wtYj9NSbTF//0i25M/VWi/WWleYz28DXtZazwReNp8LIURS8we6eGhdJV6/Edyb2jutfQ577DtPovmOVwCPmI8fAa6M4nsJIURC+Ovmau58ZicPvG50zbxzoNHa54/D4GukgrwG1iilNiulbja3lWitj5mPjwMlfb1QKXWzUmqTUmpTXV1dhC5HCCHiw2t2z9S5vGw/0sJXH9ti7XN5fDG/nkhVoTxTa31EKTUOeFEptSt0p9ZaK6X6/AjTWq8GVgNUVFTEJ8dICCEiJNjv3uELsK/WDcB1FeVsOthIvatzoJdGRURa8lrrI+bftcCTwDKgRilVCmD+XRuJ9xJCiETS5vUTCOmGcaYaYdXjC3C40UiZvOOKeZQXZHB4NKZQKqUylVLZwcfARcB24GlglXnYKuCpkb6XEEIkmsXfX8M1v1lvPff5jYDv8XVxvNVDQaaDtFQbkwoyONQY+yAfie6aEuBJpVTwfH/WWj+vlNoIPKGUugk4CFwbgfcSQoiE4gto3jvUjC/QRaotBY+ZVeMLdNHc7iMvIxWA/AwHLo/R6relqJhd34iDvNa6EljUx/YG4PyRnl8IIRJVp7/Lerz7uIvX99Rx7wu7AaOUQVN7J/kZDgCynEa4bev0k5OWGrNrlBmvQggxTO2dfutxVUObFeDBaMk3tfvIN1vymcEg7/UTSxLkhRBimNwhAftgQ3h/++4aFzuPtZKbbrbk0yTICyHEqNLe2V2yYMfRlrB9ze1GTnxxthOALKeRWun2BoglCfJCCDFMoS35bUeMIP+p5VP6PDbTYbTk3R5pyQshxKhQ7/Jajw83dgBw9qxiblw+1dqebXbTFGYZ3TZ1bk8Mr1CCvBBCDNv71c3YUxRfv3CWta04y0m6wwit2U47N51pBPzJhZmk2hR7atwxvUYJ8kIIMUz7a9uYUpTJV86faW0bn5uG0270v3/stMlWmYNUWwrTirLYc9wV02uUIC+EEMN0uKmd8vz0sG0FGQ7OmVUMwIrZxWH7ZpZksac2tkE+UgXKhBBiTPEFuqiqb6Nicj4Af/70qbx3uJmUFMWi8jwqf3gpKT1mtk4pzOTZbcfQWmNWCYg6CfJCCDEMW6ubaesMcNq0QgDOmFHEGTOKrP09AzwYg7Bd2ki9DE6OijbprhFCiGHYX9sGwLwJuUN+TbZZzsAVwzRKCfJCCDEMhxrbsaUoSvPShvyaYDplLBcPkSAvhBAnqN7t5Zev7mNaUSaptqGH0WBpg9f31PHQusqYlDiQPnkhhDhBa/cYS5V+aNGEE3pdjhnk73xmJ2AsEXj7pSdF9uJ6kJa8EEKcoP11buwpis+vmH5CryvMdIY9d8egJS9BXgghTtCRpg5K89JOqKsGYEJeeE59cKJUNEmQF0KIE9TQ1tmrVT4UDnt4yI3FAlES5IUQ4gQ1tnVSkOkY1mvv/+hSrl4ykRQFrR0y8CqEEAmnsa2Tk0pzhvXayxaWctnCUnYdd1Hjin5Fyoi15JVSNqXUe0qpf5vPpyql3lZK7VNKPa6UGt7HnhBCJBCttdldM7KQNq04k8q6tghdVf8i2V3zVWBnyPP/BX6qtZ4BNAE3RfC9hBAiLto6A3T6u4bdXRM0rTiL6qZ2PL7orhQVkSCvlCoDLgMeMp8r4Dzgb+YhjwBXRuK9hBAinhrdnQAjDvLTizPp0r3Xho20SLXk/w+4FegynxcCzVrr4KhCNTAxQu8lhBBx09BmrAYVXOlpuKYVZQFwoL6N2lYPLe3RKXUw4iCvlPoPoFZrvXmYr79ZKbVJKbWprq5upJcjhBBRdbzFGCwtzhp6zZq+BBf4bmjzsuyHL7Po+2uoaY38QGwkWvLLgcuVUlXAYxjdND8D8pRSweydMuBIXy/WWq/WWldorSuKi4v7OkQIIRLGzmOtpChjAZCRyM80KlIGu38Antl6DF+gq1c/vccXwOsfXt/9iIO81vp2rXWZ1noKcD3witb6Y8CrwDXmYauAp0b6XkIIEU+BLs3T7x9lYVneiGerOu02spx2DtR3Z9gcb/Vw9a/Wc9aPXiXQpQGj9MFpd7/MF//07rDeJ5p58t8EHlNK3Qm8BzwcxfcSQoio++Ur+6hqaOf+lXMicr6CTAc7jrZazzfsb2DbkRYA3B4/uRmpVNa5aW738dLOWlo9PnLMmvQAV/3qzUHfI6JBXmv9GvCa+bgSWBbJ8wshRKzsqXFR0+phQl46dS4vp00r5I19dUwrzuTSBeMj8h75mQ7eP9xsPQ8GeACX10duRio1rV5r294aFydPLrCev3eo+7X9kRmvQgjRw+HGdi766dqwbXvvuoRdx1xcvnhCxNZnHWhCVXD1qOMhg7Ef/vUGbr9kDp89Z+jVL6V2jRBC9LCxqrHXtld21eLy+jlnVuQSRPIzjCBvT1HWqlHjc4ysnWAZ4jU7jlOam0Z+htFNc/dzuwCsPvvBSJAXQoge/rnlaK9tG/Y3ADB93MiyakIFc+1LctLQZsz+xkWzAKNPvqXdx7q99aycN54vnTfTel2gS9Pc3tnrfH2R7hohhAjR0u6zVn4K9fv1VUB36zsSyvKN+vIpKdAZMOaSTi7MBKDV47Pe87RpBUzMy7BeV93UztPmB1F+RioHB3gPCfJCiKT2hw1VXDC3hNLc8AU7uro0hxrbmVKUSaBLM/1bz/Z6rVJYLeyg3PTUXscN16ySbABKc9JZPr2IxzYeZqIZ+Jvbffz0pT0AXDy/FK01q06fzCMbDnLpz9bR1mnkzd//saUs/17/7yHdNUKIpFXT6uG7T+3g5kd7T8h/6I1KVvz4Nb7453d5bXdtr/177ryEU8xMlkvmd2fT2CK40kfF5HxuWTmbX398KXdeOZ8t/30heeaHSDDrJthXr5Ti1ouN1M1ggAcoyhp48RJpyQshklady0g/PNLcEbb9jb31PLf9OGDMMn1m67Gw/V+/cBYOewr/d/1iGts6sduUdXwk2W0pfPHcGdbzvAwHWmtSFBxsNAqX/fz6Jdb+TKedL583g1+8ss/aNlj3kQR5IUTSqnMbQb6xrRO310+W006b18/HH357wNd99pxpgLEm64S8dGqjUFOmP0opNLD5YBMApXnhNXJKzOwbpeBvnzvdqoHTH+muEUIkJa8/wP0hLd4qs3zA8X4C9vevmGc9dtrDSxbkRXCwdShCxwEKerx3jtmdk5ueGjYxqj8S5IUQSene53ezyWwNA9SaS+3VtPQd5K9Y3H819OAC3J88Y0rkLnCIcjPCB3qDffRp9qHVzpHuGiFE0mnp8PE7M/0w6HiL0XVTGVIQ7OxZxZw9s4hpxZnkpqeSm55KS0ffdd2r7rksatfb0z1XL+C2f2wDen+rCNaucaYOrY0uQV4IkXQO1LcR6NL8/IYlrJhdTMUPXuJgYxutHh+/feMAGQ4b151Szm2XzAkLomtvORfPMEv6RlLFlP67YdLM4O60S5AXQoxRBxuM1vqc8dnkpKUyrTiTncdcvLijhsr6Nh69cRln91GeIDcjlVwilwc/XAPVtBmXbQy8fuTk8iGdS4K8ECLpHDLXTZ1UYMwSXT6jiN+vr2JRWS4Ai8ry4nVpQ5IzwISr4mwnO+5YSYZjaH3yMvAqhEg6BxvbKclxWgt7nDG9kECX5gOzdnumc2QLfkTbYBOuMp32IVfClCAvhEg6R5o6KM/vrvUSzC3fW+smPdWG3TZ2Qp901wghkk5TeyflBd1BvjTXCPKHGttJH+GyfbHyo2sWRqROztj5OBNCjBktHT6rBgxAYZaTlfNKAOjwxT97ZiiurShn5byRr0AlQV4IkXSa233k9ZhE9DOzBky2c2x1YIytn1YIkfQ8vgAdvkCvUgRpqTZ2fv9iunrWDk5yI27JK6XSlFLvKKXeV0rtUErdYW6fqpR6Wym1Tyn1uFIqtsUfhBBj0v46NwATehT2Akh32MgcYy35SHTXeIHztNaLgMXAxUqp04D/BX6qtZ4BNAE3ReC9hBBjWEuHDz1IS/y9Q80AVAyheNdYMOIgrw1u82mq+UcD5wF/M7c/Alw50vcSQoxdR5o7WHTHGn73ZtWAx9Wb5YXH5/ZuyY9FERl4VUrZlFJbgFrgRWA/0Ky19puHVAP9l3gTQohBHDYX0Xh+x8CLdzS2dZKbnkrqGMqFH0hE/hW01gGt9WKgDFgGzBnqa5VSNyulNimlNtXV9V48VwghAFLMGZ4Dddf4Al08uuFgv5Ukx6KIftRprZuBV4HTgTylVHCEoww40s9rVmutK7TWFcXFvQsGCSEEQKDLCO5dA3TJHzRr1ohukciuKVZK5ZmP04ELgZ0Ywf4a87BVwFMjfS8hxNjlMScx9ZUC6fb60VpT3WQE+Z9dvziWl5bQItGSLwVeVUptBTYCL2qt/w18E/i6UmofUAg8HIH3EkKMUe2dRpD3B7QV1MEYaJ3/vRd4aN0BqpuMBbuXTZXMmqARJ4xqrbcCS/rYXonRPy+EECPW3mnkcWw70sL8773AHZfP491DTWytbgHgrmd3WscGa64LmfEqhBglPD1qzjy3/RhvVTb2eexgpXrHEskxEkKMCvXuzrDnaf1Uk0wb4tqnY4X8awgh4ubBtZVc/ss3Bp3FCrBubx2LyvNYMNFY3am/lZEyHdJBEUqCvBAibu56didbq1twe/2DHlvT6mV6cSZPfPZ0wBiADcpOs/f5WEifvBAiTmpaPdbjWpeX7LSBF8hoau+kIMNBusPGqVMLaG7vnvD020+ewsKyXL7z5HZuOmtq1K55NJKWvBAiKurdXt4/3Nzv/gP1bdbjvTXufo8DY9C1vTNAfqZRzLYg00Fje3cffXl+Bk67jXs/sog543NGduFJRoK8ECIqKu58iSvuf7Pf/vZal9d6/O+tRwc8V2ObEdALzSCfl+GwCpFdPG+8FCMbgAR5IURU1bm9fW83g/zSSXlhLflAH3ULgkE+3wryqVZ3zcmT8yN6vclGgrwQIuJCW+8H6tr6PKbW5cFhS2HppHwONLQR6NL8+rX9TP/Ws71y4nu25CeEtNzT+smyEQYJ8kKIiAuWIAB4ZXctF/30dX7z+v6wY+pcXoqznUwfl0Wnv4tNVY08sNY45p0D4ZOcerbkb1g2ydp37mwpbDgQCfJCiIhrC0mJfOD1SvbUuLnnuV1hxwSD/LSiTACuW/2W1QWzp8YVdmzPlrzdloJSoBSU5WdE7edIBpJCKYSIOFcfee95GeEpknUuL+UFGcw3JzeFqmoI7+KpafXgsKeQE5JmuenbF1g15kX/pCUvhIi4YEveEbI6U5vXj8vTndve3O4jPyOVTKed2y4JX2dow/6GsH79w03tTMxLJyWkJk1hltPqvhH9kyAvhIg4t8cI8g+uquD1W1bw+M2n4QtofrJmT/cxXj9ZTqNl/rlzpnPftYtYVJbL51dMZ39dm5WV09zeybPbjjMxLz32P0gSkCAvhIi4YJmCwkwHkwszWTLJSHP8/foqALq6jJrwWSElCK5eWsZTXzqTs2YUAbD7uNEvv7fWSK88/6Rxsbr8pCJBXggRccEgn+U0grjDnmK1xL3+AG1mbfhsZ+9hwVnjs4HuIH/EXAjkrJmSRTMcEuSFEBEX7JMPbal/9pxpALg8/u4PgT6KiRVlOSnKclhB/miLEeSlu2Z4JLtGCBFxrh4teeiuDuny+PEHunrtD1WWn8GxFqOAWUuHD4c9hXSZ9DQs0pIXQkRcm9ePPUXhtHeHmGxzkPWxjYesBUDyM/rOjinMdFi58a0d/rDUSXFiJMgLISKu3tVJTnoqKiSPPdiSf+D1SirrjcHU8oK+u2AKQoO8x0dOunQ6DNeIg7xSqlwp9apS6gOl1A6l1FfN7QVKqReVUnvNv6WKkBBjxMaqRpaU54VtK852Wo/X728gRcGEfvrZC7KMIK+1prXDJy35EYhES94PfENrPRc4DfiiUmoucBvwstZ6JvCy+VwIMco98Pp+bn50U5/79ta4eHzjIaoa2phtZskETczvDuhvVzaQm55Kqq3vEFSY6aAz0MWNv9/I9iMtstrTCIz4X05rfQw4Zj52KaV2AhOBK4AV5mGPAK8B3xzp+wkh4uvuHjVoQt317E5e210HQElOeI13p7174LTe3cnkwv5rzhRkGq3+V/s5lxi6iPbJK6WmAEuAt4ES8wMA4DhQ0s9rblZKbVJKbaqrq4vk5QghoshnZsgAVmnglo7usgUlOc5er3nr9vNZYVaNbA05tqeCzPDumXIpQjZsEQvySqks4O/A17TWraH7tFGEos/lYbTWq7XWFVrriuJimewgxGjRZA6MvrmvnjnffZ71++qpNicuAcyb0Lvw2PjcNG5dadSpaWofKMiHf0D0N0ArBheRji6lVCpGgP+T1vof5uYapVSp1vqYUqoUqI3Eewkh4ueNvfXW48b2TtIdNj720NsAfNT8+4Zl5Xzi9CmUF/Td+u7ZV9+X0EFagEn9nEsMbsRBXhk5Ug8DO7XW94XsehpYBdxj/v3USN9LCBFfH3/4betxbauXW/66tdcxkwszOam0/8W0bSmK+z+6NGwgtqdx2T1b8hLkhysSLfnlwH8C25RSW8xt38II7k8opW4CDgLXRuC9hBAJ4hO/fafP7bnpg6c7XrawdMD9oVk311aUUZzVu39fDE0ksmveAPqr3H/+SM8vhIg/rTXXPfAWAKdMyWdjVVO/xzr6SYs8UZ8+cyq56al8+fyZETnfWCXJp0KIQe2rdfNOlbHu6orZ43oF+buums+26hYe23iYlAilc3znP+ZG5kRjnAR5IcSg9te5rcc9u06++x9z+dipk/FXdHHKlAIuXzQx1pcnBjBmgvzblQ2My0ljUkEGthRZF1KIE+HyhK/ZuuH286hp9dLU3smKWUbqs92WwodPLovH5YkBjIkgX+fyct1qoz/xq+fP5L8unBXnKxIiMW0+2Ehjm48L54bPXXSHLMw9PjeN0tx0SnMld300GBNVKOtcXuvxhv0NcbwSIRLbh3+9gc88uolb/vo+G80+eOhes/UvnzmNs2fJpMXRZEwE+eb2TutxzhDSu4QYi4yJ6Ya/bq7mow++ZT13d/px2FM4fXphPC5NjMCYCPKh06dDc3gDXZrDje3xuCQhEk6HWX8mKLSgmNvj73M9VpH4xkSQbzRb8kVZTlo6ulv1j288zFk/epX1++v7e6kQY0ZwkY6g9s7ufvhWj1/K/Y5SYyLI17u8KAXTijNpDmnVv3vIyPXdeKD/iR1CjBVNbcb/jf8289NPnty9zk+9y9urnowYHcZEkK91eSnMdFCU5WDTwSaa2zt54PX9vHPAGFiqd3sHOUN0HW/x8J8Pv011k3Qdifj597ajACwqz+XMGUUEuow++tVr97OhskGC/Cg1JoJ8nctrdtUYLZXrV7/F3c/t4pDZH1/r8sTz8vjRC7tYt7eeZ7cdG/xgISLE4wvwxt56a8D1dXOBjsmFmWSn2XF5/PgCXfzwWWOREKkfMzolfZD/4p/f5aWdNYzLScPrMxY52HXcFXZMaIplrLi9fjYfbGT12v0cbTZqcB8JqcUtRLT9/d1qPv7w2zyx6TBgJCJcPG88RVlOK8iHdm8OVFlSJK6kH0l5ZqvROi7OclLpCV+k4IKTxtEZ0KzdU8eT71Vz1ZLYzNZ7q7KB61d3p6cVZDoArG8WQsRCMIDvOu6ipcPH3lo3Z84sAiA7LZUal4efrNltHX/J/IErR4rElPQt+aC01BTuvWaR9TzTYePBT1RY5TP/6/H3Y3Ytz28/HvY8mNVwpFla8iJ2GtzG712nv4vl97wCwGSzbnt2mh2t4bGNRiv/qiUTyc2QOSajUVIH+dDJHUrBjHFZXL5oAgCTCjNRStHRGejv5VETOkU8KDvNztHm+I4NiOQS6NJh67D2FEw4aO7wWb+TJ08uAED1qB7+uXOmR+kqRbQldZBvNwP4zHFZfOPC2UD34sLBTIE7rphnHR+rLJuek04ATptWiNvrtzIahBip6x7YwLk/fq3f/cdbjEZFc3sn04ozKctPZ0GZsS5rz/8LQ1myTySmpA7yTeYkqE+fNZV8s9+7JCct7JiTSnP4zcdPBrp/6aN+XWb3zL++dCYXnFTCL25YwqlTjRZUW2fvVr4Qw7HpYBPVTR3W71tPh82U3eZ2H60dvrCaNOfO6X78209WRPdCRVQl9cBrcGApL8NhbQsGeU9IN01xtrE/Fi15jy/A+v0NLJ9RyIKyXB5aZfwH+ss7hwBo8/rJSZO+TzEyoYX49te5qcgsCNvvC3RxvNVo1NS0emls6yQ/pM/9vDkl7P/hpVKWOwkkdUs+GOTz+wjyoV0mhZlG1029u+8WT6RsPtjEnO8+D0BlXVvYvkyzLkhbH/31I/XHtw4y5bZnaGn3DX6wSArr9tZZjyvrw3/XXB4fx5o9BIes6t1eujQsmxpefEwCfHKISJBXSv1WKVWrlNoesq1AKfWiUmqv+Xf+QOeIhmB3TWgLJSfdCKahA1LjzH76Y1HObnltd631+KfXLQ7bl+U0ikG5vQFe3lmDf4ABsxP1x7cOAt1fz0Xyq6xrY0phBqk2RWVdG794eS8rf7oWt9fPyT94ibPvfRWA0tzu7suKyTH/LypiIFIt+d8DF/fYdhvwstZ6JvCy+TymgiWGQ1O/Zo7L5vpTyvm/6xdb2zIcdsry09ld4+p5ihHbV9t9zk5/d+AO9sEHZTqMD59/vX+Umx7ZxOp1lRG7huDK9396+1DEzikSlz/QxVsHGlgyKZ9JBRmsXrufn7y4h901LuZ/7wU6QxoQoUE+U6pMJqWIBHmt9VqgscfmK4BHzMePAFdG4r1OxLEWD/YUZXXHgPEV9J4PL2TO+PDZezPGZVHV0NbzFCPy/PZjXHDfWtbsMPLig3nwq06fjFLhX4ULs4wupS2HmwGoqo/ctdhtxnv95Z1DHGsxrmH7kRaW3/NK2LcLkRxqXV6a232cMqWAsvwMBkrYKsvPiN2FibiIZp98idY6WIzlOFAy0MHRUN3UwYS89CH1LRZkOqwqfJGyt8ZY/Di4wk5VQxtnzyrmjivm9zp2cmEmqTbF5oNGRcxgnvKf3z7EsrteCsv570ub199vzn9qSvdtDo5TPLHpMEeaO3j3oFTgTDbB9Vhz01P55PIpAx4bTI1U0v2etGIy8KqNCNVnlFJK3ayU2qSU2lRXV9fXIcN2pLmDiXlDW4cyL90RtoJUJLV1Bjje4mHPcTdz+sk3TrWlcMqU7i6cxzcdZsvhZr715DZqXd5BB4Xnfe8Fq5+1p9A64MEgH6zA6fbGfjKYiK5Ws3xHTrqdopBvsT3XbQWYa9ajOX/OuNhcnIi5aAb5GqVUKYD5d5/9Alrr1VrrCq11RXFxZNeObHB7KRpiedRUm6KtM8BDEewLrzULn3l9XfzxrYMEtOY/T5vc7/FXLZkY9vw3r+23HgcHTZ9+/yhTbnuGa3+zoVfrPrTQ2nf/uZ0r7n+TQw3tdAa6cNqNW91izm4MFmkLVuYUyaPVvKfZaakUZHVnln370pN6HVuY5eDfXz6Tn12/JGbXJ2IrmkH+aWCV+XgV8FQU36uX7UdaqGpoJ2+Ia7oGA+QvXtkXsWtoNv+zub0+DjW2U56fTnlB/32g04ozw54/v6O7xk21WaHyWbPg2jtVjbjMdMu+unL+8NZB3j/czNn3vsr7h5uZWmSc+74Xd1Pb2j3pS4J88gl21+Sk2Rmfk8ZVSyby9JeWU5pnDLJ+48JZ1rHpqTbmT8yVQdckFqkUyr8AG4DZSqlqpdRNwD3AhUqpvcAF5vOY+drjW4ChlxH+8vkzAZg3IXLlVFutIO+nsa3TqjbZn56zcUMFFxQ5EDIg++j6KgB2HG0NOzY4BmBdh8fP/InGdPU9NW7O+8nr1r6XdtbEpX6PiJ7u7ppUbCmKn163mIVleTjtNqruuYwvnTfDOjZXFrZPepHKrrlBa12qtU7VWpdprR/WWjdorc/XWs/UWl+gte6ZfRNVNnMkKVirZjBTizK5cG5JRGe9Bv+zuT1DC/L9rbxTmOngcKPRkq91eayf6cdr9gCw5oMa69hAl+auZ3b2Okd6qq3XtkVmnZL9de7BfhQxinR31/TdOg/N7JLVnpLfqJzxuuVwM/tqBw5MwV/eb14yZ8jnLclxsqfGbU0eGok399Xz3qFmwPj6XO/2hs287YvT3jsQf37FdMry0/nLO4e465kPaGr3WV0vQaEfTDWtHupcXi5dMJ5UW/d/5i+dN6NXoP/GRUbRtmMxqtkjYsPl8eO0p/T5+xT08xuWcOeV83ul8orkMyqD/JX3v8kF973OlNue6beU6tGWDi6ZP54Mx9D7GsdlG90l3/mnNXEXjy/Av7cepaXdxy9f2TukmagfHG3lYw+9bT2vrG+j1uVlYXneoK+9YVk5d13VnWL5zYvnUGb24z+47gAA58wKz4TYday7u2bTwSYrq+jN284jNz2VR29cRklOGlu+dyFPfPZ03vnW+ez6wcVWpk8kc/JF/LV6fOQM0g1z+aIJfHyAJACRPEb9aEt1U0evlq3WmuMtHlbMOrG0sPEhfeItHT6ynXb+9/ld/O7NKqYVZVJZ38ac8Tlc0EcqWqjvPtX9IbGoPI/3zQlO584ePHvo7qsXAkadm5njjCDcMw10UVku/7GwlA+OtrLzWCvvHmpmVkkWVfXtfOUv7wHQ0NbJuOw03v/eRdbrnHYby0Jm2jrtKcwcl8WaD47zmbOnGf9urR5Kc4eWdioSU2uHv9+uGjH2jMqWfKi+um1aO/y0dwbCpmwPxWnTugs0LbpjDR9/+G0ONRgDnsEiT8GMmZ3HWq0+956C3SQZDhvXVnQvKTjUnH2A+65dzOdXGAs1jOvRb7qoPI8Mh43K+jYu+dk6AD5z1jROm959/ZctGHypNqUUM0uy2H6klf95egdX/mo9p9/9SsxKLovoaPX4pJKpsIz6IB9aUjWooc3ooy7KHrgPvKdJhRnce81C6/n6/Q29UgyPNHXQ1aW55GfruPF3G/s8TzBb5R9fOIMphca3jDsunzfs/s/QDx+HPYVMp53dNeEfbstnFOE2P3R+8/GlnH/S0CYYZzrsdPgC/H59lfWN42CEyzuI2DpQ33ZCDQqR3EZ9kN/TR1GxYJ5wtvPEWzNXLZnIsqkFlBcY/0l6Vm5s6/RbgX9TPyUBGts7uWrJROaMz2H5jCJev2UFq86YcsLXEjR/Yi53X70AAKdZbCx0dq49RTE+J41bVs7hrJlFrJg99G6qvvKjvx0yJqG15gf//sAqtyASW2NbJ9VNHSw0M6eEGHVBPnTg8/w546hp7d21YE0GGUYOsN2WwhOfPZ3/u86YAVjTGp5S2eb109DPSjtBje5O8kIqX04uzBzg6KFZVJYHwMXzxwNwXsg09D99+lRSUhSnTy/kDzedSlof6ZL9yTKD/ITcNCaZA7yhXWC+gObhNw7w4V+vH+mPIGJga3UzgLWMnxCjLsh7zHK9t18yh7L89D6DfLCvfCSDT8VZfecPd3QGrDr1odbuqeOR9VW4vX7aOgMDTmwajrkTcvjdp07hh2aL/tuXnmSliU4rzhr2ef1micJrKspZe+u51jmDs2g9fpkolahe3V3Lq7tr8YQsgPNvc0Z0cPKbEKMvyJu/0OkOG8XZTlo9frw9ApErAkG+MKt3f75R38ZPQ49iYVprPvHbd/je0zuskgFDnYR1Is6dPc6qDW+3pfDUF5dz7zULRzShJdj/PrXIaMV/5qypAMw2V7DyyGzYhLSnxsWnfreRT/1uI/c8twswuvD+trkaQAZehWXUBvk0u41s8xe5sUf3SbDPfDjdNUGZTjufO8fIbpmQm8aOO1Yyb0Iu7T1a8l5/gL9uqraeB9fNLMmObEu+LxPy0vlIRfmIznHTmVMpznZa6abBD4xOfxdefwCPr7t7rGugwuQipnYf7x6L2lPjotblYfH3XwRg5byYV/UWCWzUBflg5oozNcXqTz797lfCarrUtHpJT7WRPcKiS//volmUF6Tz7cvmkum0k+Gw0d4ZCPtQOVDfxq1/3xr2HGBchLtroqViSgEbv30B+WbJheKs7uveecwV1l0THOsQ8dHq8XHpz9Zx35rd7DrePQEuLdXGsrtetp6vOn1KHK5OJKpRN2Piwp+uBaA0Nz2sRf3GvnprUtTxFg+luWkjnrJtt6Ww7tbzrOcZDjuNbe1hQf5Yc/iYwB6zhRWN7ppYGBdy3duqm1loDviCsWZu6FKKIrZe3VXLB8da+eBYK+fNGYfTnoLX38Uru8KreOcPUiNJjC2jriUfNKkgI6ylftxc1q6jM8DaPXVMzI98nnB2mh23109TSJDvmWK585iL9FSb9S1jtCkKGXBe80GNNecAuuvjg/GN5e3K3nMURGQcqG/rVUNpU1V3Gusru2pZOW88Z80s6vXawWokibFl1Ab5cdnOsBzv4y1GANpX68bl9fOhhRMi/p656am0tPtoaOukMDN8Tdagd6oaKclxjtrCT/kZqXz8tEkArNtbz42/32Ttqw75QLv50U1ct/otjprr1orIuu6BDXznn9utMaimtk7+0CPol+Wn95kFlifftkSIURXkg5krt6ycTUqKCmuxBFMpj5ot+rkRrAsflJeRisvrp87ltbqG/vHuEWt/hsPITx8t/fF9UUpx55UL+qwzXt3Ugcvj48bfb2SvmUsfXMxERFbwW1NwTkZlvfHvfeXi7sbL9adMslY+u+nMqdb2E5knIZLfqAryn/vjZgD8ASPLY1JhBi987WxWzivhWEsHhxvbuftZo5b6idatGYrgKlMfHGvttcLTnz59KmVmF1HPWjPJorXDxx/fOhTWB9zWKYOx0dRopuvWmpPyPnP2NDIdNs6eVcykwgzrw7hrkIXexdg1aoL8sZYO3jXrsy+elGdtnz0+m9LcdGpavXzkNxuoMguK5UWhXzJ00DE/w8FHTu4uPjY+N82qFxLpiVDxVpjpYFy2E7fXT056+FhDm1eCfDTVm2MiwW+q43PS2PzdC3l4VQUAHzt1EmfOKOLqJWX9nkOMbaNmdHDHke6UsXNmhZfsnVSQgdvrxx0ScGwpke8TnxTSer9kwXiq6tv4a8jkk+AHy2jNrAk1IS/dmm9w+6Uncf+r+3hs42He6bG0YLtXJktFg8OWQmegi79trqYkO42tR1rIz0glP8NBSsjvdl6Ggz9++lQAls8oJGWUjgWJ6Bk1QT5Y4veyhb1L6IZWaYym2eONfv5F5XmcMqUgrBWbnWa3Sgynn8BCJYnqFzcs4YfP7uSXH11ChsNudYNV1hnzANbfdh5n3PNK2AeriByH3Qjyz2w9xvp99RRmOamYUhAW4Hv606dPi+EVitFi1ESj4NfVH1+zqNe+yYUZvbZFQ5bTzp8/fSqzzRWVQtMN01JtFGQaz4OVIkezGeOy+O0nT7Ge9yzKFiz70C598hHn9Qd6fXjWtHg4c0bvdEkhBhP1aKSUulgptVsptU8pddtwz9PS4SMtNYV0R+/Mgb7K5UbLGTOKKDSDe88B1i+fN4OvnD+TK5dMjNn1xEN6qg2n3YbDloJbumsibt2eegA+eqqRylqSk4bL60+6sR4RG1EN8kopG3A/cAkwF7hBKTV3OOdye/1DnmA0lGX2IqGgx8zCTKedr184C4d99Lfke3rs5tNYZK5R22Hmbmc6bdKSj4JXdhvZSx85uYwLTiphlzmLOhoT/ETyi3YTeBmwT2tdCaCUegy4AvjgRE/U5vUP2GK/79pFZKelcuEg669Gkt2Wwo+uWcjSkGyfZHXatEJ+eNV8Lvv5G9a2DIdd+uSjIEUZDYglk/KtuRcOewrnzIxN40Ukl2gH+YnA4ZDn1cCpoQcopW4GbgZIGz+93xO5PQO35K9eGp8UsmtHWAVyNJlVYoxFnG8uWJLltEsKZRS4PN0LcQeD/JkziqRukBiWuA+8aq1XA6sBnKUztda6V0kArTUv76odEy3mRJZqS2Hzdy6wUkUznEZVThEZLe0+rv71m7R6/NZ4T3D26pQIrC4mxqZodx4fAUKbumXmtn51+HoHjWB9mOBkKBE/hVlOaw5CllO6ayLpvcNN7K9ro87ltVrywZms0ZjBLcaGaAf5jcBMpdRUpZQDuB54eqAX9BU0gnXMC6WEakLJcNh471CztVSgGJlAyKIsWeYi9NPNpR1nlAx/iUcxtkW1u0Zr7VdKfQl4AbABv9Va7xjoNW6Pn3HZ4duCdeMf/6xM9kgkwRb9gv9Zw5JJefzhplMHeYUYSHCGMXTX9V91xhQuW1gqDRwxbFHvk9daPws8O9TjQ1vy9724h7V76jjPHOgrzBz95QKSydcvnMWz247j9vpZt7eeJ9+r5iqpoXJC6t1ePjjaSocvwNefeN/aHjoHo6ifReWFGIq4D7z2tOVw92pEP395r7XNnqJGtGariLyy/PCZxv/1+PsS5E+A1pqbfr+R96tbCK1WMD4njfPnyDqtIjISbtbOe/0Mri6ZlBeVomNi+NJSbdx89jTmmbX7F0zMjfMVJY6WDh9ff2ILmw829tqntUZrzfr9Dbxf3QJA6Brpb33rfBaUyb+liIyECvJpqTZrkNVIpYQblpUzZ3w2d1w+P85XJ/ryrUtP4pmvnMXi8jxZkSjEpqpG/vHuET786w08uqEqbHD6O//cztTbn2Xtnjoc9hTOniWTnET0JFSQtymFy2MMPrV3BtDayA9+/mtnR2WlJxE5OemptIYMHI51oevh/vdTO1jzQY31/E9vHwLgUGM7E/PS+cX1S2J+fWLsSKg+eVtKd7rkoUZj8Y+stIS6RNGP3PRUDjW0xfsyEkZwJaeglvbeH4B7alyMz0kjNyOVdbeeS3VTR8wqqoqxI6Fa8ilKWdk1H/71egA6/V3xvCQxRLnpdlo9MjEqqNZllMb+w03LACOg97S/ro3SPGOSU3lBBqdPL2RCnhQhE5GVUEHelqI43uLhsXcOWdPl54yXbprRIDc9lZYOn0yMMtW6vMwuyeYss6jYQ28cwB/owh8Ib7RMLpByBSK6EqovJMNppzPQxW3/2AbANSeXcfr02Kz6JEYmJy2VQJemrTMw5JLQyazO5bUmNC2YmMu2Iy08s+1Yr287s2Qmq4iyhGrJ54XkwX/l/Jn8+CO9V4ESiSnXvHcy+Gqoc3kpNic0/fGmU0lR8NXHtvDdf24PO+7i+ePjcXliDEmoIB/qDGnBjyrBIN8yhoL83hoXD62r7NUFo7U2WvLZRn97bkZq2IIfS8xqqpcuGN+r4qoQkZaw36t7Lq0nEluReb9qWj2cVDo2xlFW/fYdjrZ4WDo5n6WT8q3tze0+OgNdYb/DRsGxDgAWTszlsZtPw56SsG0skUQS9rdsnKxnOaoEU/+q6sdGGqXWmqMtRgZNe491boM58sUhQd4eMls7zVwjV2Zwi1hIuCB/wzJj8WIZvBtdirOc5KTZ2Xmsd6pgMgpdLKXnGgjB9MnQlnxoPL/prKnRvTghQiRckL/ryvnsveuSeF+GOEFKKc6YXsT6yvp4X0pMNLZ1Wo97Bvk6syUf+m00xYzyP79hidVXL0QsJFyQT0lRpNoS7rLEEMwan011U0fCTWA7UN9GZZ07Yjn87Z1+7n5up/Xc09l3d01oS77crNiZbi7nJ0SsSJ+IiJjy/HS0hiPNHUwtSpxJPuf++DXACLAbv3MBDlsKXVpb66eeqJ+s2cOz245bz3t117R6yXTYyAzpcvzh1QuYU5rN8hmSNSZiS5rMImImFRit1cNm3aFE0+EL8PLOGi766essumPNsM9zqMfP99LOGn70/C5r+b5al6dX4kCW084XVswgwyHtKhFbEuRFxJSbQX738cQdfP3qY1uoamjHO4IupbYe6xCv21vPr17bz1uVDYDRXVMsqzmJBCFBXkRMidl6vevZnYMcGTtdXf33w3t6dLMMVej8pdDUyANm+midy0txjgR5kRhGFOSVUh9RSu1QSnUppSp67LtdKbVPKbVbKbVyZJcpRgNbimLmuMSqxfLA2koArl4ysde+o80dQzrHtuoWXtnVXQ/e4zO+BVy9dCIzQn7eYDeOMdtVgrxIDCNtyW8HrgbWhm5USs0FrgfmARcDv1JKSVrBGHDVUiOYujy+Xt0a8fDCDmOANNWWwudXTA/bV900tCD/oV++wY2/32Q9b+nwceHcEn58zSLu/9hSHvpEBbNKsqiqb6O904/b65c0SZEwRhTktdY7tda7+9h1BfCY1tqrtT4A7AOWjeS9xOiQl+4A4KMPvs28770Q56uBbHPRmdsvnWPV1wm665md3P/qviGfy+ML4At00dzuoyjLQUqKYnpxFhfMLWFSQSZVDW3WYiHSkheJIlp98hOBwyHPq81tIskF13nddsRYoHokBcs8vgAf+sUb/PKVvcM+R53Ly4VzS8jLcJDfYw3a3TUu7n2hrzZK306/+2Uq7nyJereXgkxH2L6JeWnUtHq7c+SlT14kiEGDvFLqJaXU9j7+XBGJC1BK3ayU2qSU2lRXVxeJU4o4Ck76CfrJmqEH0Z721rjZdqSFH6/ZM+xzNLV3UpBhBOT+ulAa3N4+t/c+l8/60JrRY+whL8NBS4ePax/YAITXrREingZN2tVaXzCM8x4BykOel5nb+jr/amA1QEVFhSwrNMrNn5jDtKJMKs1Mk0c3HCQvPZWvXzT7hM/l8o6sbLHXH6Cm1UteptGC7691fazFQ6GZ8ni4sZ1xOU6c9u4hJFuKsnLgg1bMGhf2vGfLXvrkRaKIVnfN08D1SimnUmoqMBN4J0rvJRKIUorFZr30oJ+/sm/AVMb+uHqsorTlcDP7aoeeg//wGwcA8JrZMCUhE5TW3XqutShNndmS9wW6OOtHr/KVv7wXdp40e/h/k7mlOeT3COp5PbqCenYNCREvI5p+p5S6CvgFUAw8o5TaorVeqbXeoZR6AvgA8ANf1FoPLylZjDpzS3P4B0eYXZLNbnMB6zf21XP2rOITOo87JMhX1rm58v43Aai65zJre73bS8WdL/GLG5bwoUUTwl4frClzbYXxpTLYbQPdE7egu6BYsCvmhR3d6ZJHmjto6wxwy8rZnDG9kE5/F9P7SBPt2ZKXxUBEohhpds2TWusyrbVTa12itV4Zsu8urfV0rfVsrfVzI79UMVqsOmMK9127iKuXdo+1f+K373DcrL9+rGVoqYvukBTMdw81W49DvxXsrXED8OiGql6v93VpUm2Kk0qzge5KkEFFZhdNzyAfalNVIwDnzRnHkkn5nDqt0HpdqPyQD5Ct/3PRgD+XELEkM15FxKXaUrh6aVmvapQX/2wt6/fXc/rdr/DctmMDnuNIcwePb+xO0Pp/f33feuzu9OMLdNHp77Jy8Zvbfb3O6fb4yXLa+21VpztsZDntfQb5R9ZXsf1IC/96/ygAhVmOPs8RFOy+Kcx0kJMmXTUicUiQF1HzsdMmc+HcEv5wkzFFQmv44GgrAG8faBzwtcvveYUPjrXisPf+FW3t8PHpRzax9AcvcrjJmGW6t9bN5//0bligd3v9ZKWF90jec/UC/udDc63nxdlO6t29g/zW6hY++uBbvLSzFmDQwB3sg5+SQNU3hQApNSyiqCDTwYOfMKpdnDw5H3uKslrVvsDQCoSlp9p6fSNwefy8vsdIt31qy9GwfV/487scuPsy6zhjbdVu15srjwUVZzmprGvjU797h1d3d6fw/v3d6rDjBitLnJ5qw2lPsZZBFCJRSEtexERhpoPmdh8t7caKSgNVgQxd3MPRR+BsDWlxbznc3ON9uvvL3V4fWc6Bg/PCslw+ONYaFuCHQynF96+Yx43LZWk/kVgkyIuYyMtIpaGt05oRWtPqsfa5vX4q69zWc1fIgGuGw8YzXzmLJ79wBj+/YQnQPZu2p5Mn59Pq8VkfEm3ewKBrBZ/RxyIe7333wrDn9iEuuH3dKZOYPzF3SMcKESvSXSNiYlF5Hk9squYxczA1dOGNW//2Ps9uO86fP3MqZ0wvotHdvX7qpIIMspx2lkzKZ0JeOgB3PhNeyvieqxewZFI+6/fXs/lgE03tPgoyHbi9/kH7yEtyek9ays90cM/VC9h2pIXvXDa3j1cJMXpIS17ExBnTi8KeH2xo55/vGZOgtx8xBmO/8+R2ABrNLp38jFT+98MLrdeU5KRx6YLxvc49MT+d2eOzKc01AnYwRdNlZtcMZHwfQR6Mvvu7rlpAusNGukMKqIrRS4K8iIkJed3BdNmUAqYVZXLL397ncGO7lZ54tKWDri5NU5sR5H/3qWVW6z3oisW969wFM1/G5xrHBvPxh9InX5Dp4JaVJ15yQYjRQoK8iInQWjCleWn84dOn4u/S/HVztbWiksfXRb3bS6MZ5ENnqAadMd3oQ788ZHZrjllCuLsl78Ef6MLj6+qVXdOTUoovnjvDev7S188Zzo8nRMKSIC9i5ntmfnphppOJeenMLc3hiY2HaW73WSUJDje1882/bwWgoI8JSNlpqey4YyX3fqS7GydYJ74oy4ktRXG8xcO6vfUAZA7Sku+pZ3VJIUY7CfIiZq45uYyPnFzGl88zWs6zSrI5bmbZLDdb6Ica2wlWLcjspy8802nHabfxu0+dwrmzi60gH6wW+ctX97F6bSX2FMUFJ5UM6dqWTMqT8sAiKUl2jYiZ7LRU7jUrP0J4q3lBmZF6+F+PG+ULfnDl/EGLfJ07exznzh7X5753DzVxwUklQ56B+uQXlg/pOCFGG2nJi7iZGhKAJ/YYYJ1bmjOsc/7s+sWAMdmqZ/lfIcYiCfIibs6a2Z1WmZOWypWLuwdTZ5UMr2986aR86/Fg6ZNCjAUS5EXcZKel8tQXl/OtS+eQkqJYdcaUsH3DEcywAazVqYQYy6SpI+JqUXkei8rzADhpmF00oey27nbL5T0WERFiLJIgLxJGWqqN1f95MuNzR7Y+6oKJudhSFFcu6T1xSoixRoK8SCgXzetdtuBE/evLZ0bgSoRIDtInL4QQSUyCvBBCJLERBXml1L1KqV1Kqa1KqSeVUnkh+25XSu1TSu1WSq0c4DRCCCGiZKQt+ReB+VrrhcAe4HYApdRc4HpgHnAx8CullNRrFUKIGBtRkNdar9FaB5fxeQsoMx9fATymtfZqrQ8A+4BlI3kvIYQQJy6SffI3As+ZjycCh0P2VZvbhBBCxNCgKZRKqZeAvvLavq21fso85tuAH/jTiV6AUupm4GaASZMmnejLhRBCDGDQIK+1vmCg/UqpTwL/AZyvgysowxGgPOSwMnNbX+dfDawGqKio0H0dI4QQYnhUd1wexouVuhi4DzhHa10Xsn0e8GeMfvgJwMvATK11YJDzuYDdQ3z7XKAlAsec6LHxOi6e7x2Nn6UIqI/De8v9i+05h3qfh3rOZPq3ieR7z9ZaZ/e5R2s97D8YA6qHgS3mn9+E7Ps2sB8jaF8yxPNtOoH3Xh2JY0702HgdNxqu8QR/liHd60T/WZLp/kXpvePyf3qU/NtE7L0H+nceUVkDrfWMAfbdBdw1kvMP4l8ROuZEj43XcfF872j8LEOV6D9LMt2/aJ0zku+dTP820XjvXkbUXRNpSqlNWuuKeF+HiD6512OD3OfYGOjfOdHKGqyO9wWImJF7PTbIfY6Nfv+dE6olL4QQIrISrSWf9JRS7kH2v6aUkq+3o5zc57FhNNxnCfJCCJHE4hLkB/v0S3ZKqRVKqX+HPP+lOaks6Yzley33eWxI9PssLXkhhEhicQvySqkspdTLSql3lVLblFJXmNunKKV2KqUeVErtUEqtUUqlx+s6xcjJvR4b5D4npni25D3AVVrrpcC5wE+UUsrcNxO4X2s9D2gGPhyfS4waP+H/9iNbuTrxjdV7LfdZ7nPcxTPIK+CHSqmtwEsYpYhLzH0HtNZbzMebgSkxv7roOgjMVUo5zdW0zo/z9UTbWL3Xcp/lPsfdiMoajNDHgGLgZK21TylVRfcnoDfkuACQFF/tlFJ2wKu1PqyUegLYDhwA3ovvlUXdmLrXcp/lPsf3ysLFM8jnArXmL8O5wOQ4XkuszMMo2obW+lbg1p4HaK1XxPiaYmGs3Wu5z3KfMbeviPE19RLzIB/89MNYYORfSqltwCZgV6yvJZaUUp8DvgJ8Lc6XEjNj8V7LfZb7nGhiXtZAKbUIeFBrLWu+Jjm512OD3OfEFtOBV/PT7y/Ad2L5viL25F6PDXKfE58UKBNCiCQW1Za8UqpcKfWqUuoDcxLEV83tBUqpF5VSe82/883tSin1c6XUPqXUVqXU0pBzrTKP36uUWhXN6xYnLsL3+nmlVHPoVHGRGCJ1n5VSi5VSG8xzbFVKXRfPnyupDXX5qeH8AUqBpebjbGAPMBf4EXCbuf024H/Nx5cCz2Hk254GvG1uLwAqzb/zzcf50bx2+ROfe23uOx/4EPDveP9c8ic69xmYhbHuMxjrQB8D8uL98yXjn6i25LXWx7TW75qPXcBOjAkSVwCPmIc9AlxpPr4CeFQb3gLylFKlwErgRa11o9a6CXgRuDia1y5OTATvNVrrlwFXDC9fDFGk7rPWeo/Weq95nqNALUaOvYiwmA28KqWmAEuAt4ESrfUxc9dxumfFTcRYGDyo2tzW33aRgEZ4r8UoEan7rJRaBjgwc85FZMUkyCulsoC/A1/TWreG7tPG9zUZ/U0Scq/HhkjdZ/Pb2x+AT2mtuyJ+oSL6QV4plYrxy/AnrfU/zM01wa/m5t+15vYjQHnIy8vMbf1tFwkkQvdaJLhI3WelVA7wDPBtsytHREG0s2sU8DCwU2t9X8iup4Fghswq4KmQ7Z8wR+RPA1rMr4AvABcppfLNUfuLzG0iQUTwXosEFqn7rJRyAE9i9Nf/LUaXPzZFc1QXOBPja9tWYIv551KgEHgZ2ItRra7APF4B92P0zW0DKkLOdSOwz/zzqXiPWMufqN7rdUAd0IHRh7sy3j+f/InsfQY+DvhCzrEFWBzvny8Z/8hkKCGESGKy/J8QQiQxCfJCCJHEJMgLIUQSkyAvhBBJTIK8EEIkMQnyQgiRxCTICyFEEpMgL4QQSez/A7wA2TxesCU3AAAAAElFTkSuQmCC\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))\n",
"ts = ts.cumsum()\n",
"ts.plot()"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 82,
"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": [
"df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=['A', 'B', 'C', 'D'])\n",
"df = df.cumsum()\n",
"plt.figure(); df.plot(); plt.legend(loc='best')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Writing/reading to/from csv"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [],
"source": [
"df.to_csv('foo.csv')"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Unnamed: 0 \n",
" A \n",
" B \n",
" C \n",
" D \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 2000-01-01 \n",
" 1.948741 \n",
" 1.330376 \n",
" -0.106148 \n",
" -1.425121 \n",
" \n",
" \n",
" 1 \n",
" 2000-01-02 \n",
" 1.142802 \n",
" 0.684310 \n",
" 0.682617 \n",
" -0.570491 \n",
" \n",
" \n",
" 2 \n",
" 2000-01-03 \n",
" 2.110364 \n",
" 1.004728 \n",
" 0.605664 \n",
" -0.075320 \n",
" \n",
" \n",
" 3 \n",
" 2000-01-04 \n",
" 4.387585 \n",
" 0.731106 \n",
" 0.245145 \n",
" -0.955636 \n",
" \n",
" \n",
" 4 \n",
" 2000-01-05 \n",
" 4.028810 \n",
" 0.866706 \n",
" 2.099975 \n",
" -0.306223 \n",
" \n",
" \n",
" ... \n",
" ... \n",
" ... \n",
" ... \n",
" ... \n",
" ... \n",
" \n",
" \n",
" 995 \n",
" 2002-09-22 \n",
" 21.901936 \n",
" -28.037157 \n",
" 24.823378 \n",
" 33.246643 \n",
" \n",
" \n",
" 996 \n",
" 2002-09-23 \n",
" 22.032930 \n",
" -26.960648 \n",
" 24.149946 \n",
" 32.554474 \n",
" \n",
" \n",
" 997 \n",
" 2002-09-24 \n",
" 21.331010 \n",
" -24.985795 \n",
" 23.597978 \n",
" 33.058872 \n",
" \n",
" \n",
" 998 \n",
" 2002-09-25 \n",
" 21.596796 \n",
" -23.555550 \n",
" 22.125744 \n",
" 35.198855 \n",
" \n",
" \n",
" 999 \n",
" 2002-09-26 \n",
" 20.331563 \n",
" -22.874957 \n",
" 22.867146 \n",
" 36.463493 \n",
" \n",
" \n",
"
\n",
"
1000 rows × 5 columns
\n",
"
"
],
"text/plain": [
" Unnamed: 0 A B C D\n",
"0 2000-01-01 1.948741 1.330376 -0.106148 -1.425121\n",
"1 2000-01-02 1.142802 0.684310 0.682617 -0.570491\n",
"2 2000-01-03 2.110364 1.004728 0.605664 -0.075320\n",
"3 2000-01-04 4.387585 0.731106 0.245145 -0.955636\n",
"4 2000-01-05 4.028810 0.866706 2.099975 -0.306223\n",
".. ... ... ... ... ...\n",
"995 2002-09-22 21.901936 -28.037157 24.823378 33.246643\n",
"996 2002-09-23 22.032930 -26.960648 24.149946 32.554474\n",
"997 2002-09-24 21.331010 -24.985795 23.597978 33.058872\n",
"998 2002-09-25 21.596796 -23.555550 22.125744 35.198855\n",
"999 2002-09-26 20.331563 -22.874957 22.867146 36.463493\n",
"\n",
"[1000 rows x 5 columns]"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.read_csv('foo.csv')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}