Skip to content

Instantly share code, notes, and snippets.

@wesm
Created October 27, 2012 17:57
Show Gist options
  • Save wesm/3965515 to your computer and use it in GitHub Desktop.
Save wesm/3965515 to your computer and use it in GitHub Desktop.
LFPUG_20121027
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "FinanceChClean"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"from pandas import Series, DataFrame\n",
"import pandas as pd\n",
"import numpy as np\n",
"pd.set_printoptions(max_columns=12, notebook_repr_html=True)\n",
"def side_by_side(*objs, **kwds):\n",
" from pandas.core.common import adjoin\n",
" space = kwds.get('space', 4)\n",
" reprs = [repr(obj).split('\\n') for obj in objs]\n",
" print adjoin(space, *reprs)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"close_px = pd.read_csv('../ch11/stock_px.csv', parse_dates=True, index_col=0)\n",
"volumes = pd.read_csv('../ch11/volume.csv', parse_dates=True, index_col=0)\n",
"prices = close_px.ix['2011-09-05':'2011-09-14', ['AAPL', 'JNJ', 'SPX', 'XOM']]\n",
"volume = volumes.ix['2011-09-05':'2011-09-12', ['AAPL', 'JNJ', 'XOM']]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Data alignment / munging\n",
"-----"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vwap = (((volume * prices).sum()) / volume.sum())\n",
"vwap = vwap.fillna(vwap.mean())\n",
"vwap"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 5,
"text": [
"AAPL 380.655181\n",
"JNJ 64.394769\n",
"SPX 172.358079\n",
"XOM 72.024288"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"((prices * volume).sum() / volume.sum()).dropna()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 6,
"text": [
"AAPL 380.655181\n",
"JNJ 64.394769\n",
"XOM 72.024288"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"prices"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 7,
"text": [
" AAPL JNJ SPX XOM\n",
"2011-09-06 379.74 64.64 1165.24 71.15\n",
"2011-09-07 383.93 65.43 1198.62 73.65\n",
"2011-09-08 384.14 64.95 1185.90 72.82\n",
"2011-09-09 377.48 63.64 1154.23 71.01\n",
"2011-09-12 379.94 63.59 1162.27 71.84\n",
"2011-09-13 384.62 63.61 1172.87 71.65\n",
"2011-09-14 389.30 63.73 1188.68 72.64"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"volume"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 18173500</td>\n",
" <td> 15848300</td>\n",
" <td> 25416300</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 12492000</td>\n",
" <td> 10759700</td>\n",
" <td> 23108400</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 14839800</td>\n",
" <td> 15551500</td>\n",
" <td> 22434800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 20171900</td>\n",
" <td> 17008200</td>\n",
" <td> 27969100</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 16697300</td>\n",
" <td> 13448200</td>\n",
" <td> 26205800</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 8,
"text": [
" AAPL JNJ XOM\n",
"2011-09-06 18173500 15848300 25416300\n",
"2011-09-07 12492000 10759700 23108400\n",
"2011-09-08 14839800 15551500 22434800\n",
"2011-09-09 20171900 17008200 27969100\n",
"2011-09-12 16697300 13448200 26205800"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"prices.ix['2011-09-09':, ['AAPL', 'JNJ']]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 9,
"text": [
" AAPL JNJ\n",
"2011-09-09 377.48 63.64\n",
"2011-09-12 379.94 63.59\n",
"2011-09-13 384.62 63.61\n",
"2011-09-14 389.30 63.73"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"pd.concat([prices, prices], axis=1, keys=['source1', 'source2'])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"4\" halign=\"left\">source1</th>\n",
" <th colspan=\"4\" halign=\"left\">source2</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 66,
"text": [
" source1 source2 \n",
" AAPL JNJ SPX XOM AAPL JNJ SPX XOM\n",
"2011-09-06 379.74 64.64 1165.24 71.15 379.74 64.64 1165.24 71.15\n",
"2011-09-07 383.93 65.43 1198.62 73.65 383.93 65.43 1198.62 73.65\n",
"2011-09-08 384.14 64.95 1185.90 72.82 384.14 64.95 1185.90 72.82\n",
"2011-09-09 377.48 63.64 1154.23 71.01 377.48 63.64 1154.23 71.01\n",
"2011-09-12 379.94 63.59 1162.27 71.84 379.94 63.59 1162.27 71.84\n",
"2011-09-13 384.62 63.61 1172.87 71.65 384.62 63.61 1172.87 71.65\n",
"2011-09-14 389.30 63.73 1188.68 72.64 389.30 63.73 1188.68 72.64"
]
}
],
"prompt_number": 66
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df = pd.concat([prices, volume], keys=['price', 'volume'], axis=1)\n",
"df"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"4\" halign=\"left\">price</th>\n",
" <th colspan=\"3\" halign=\"left\">volume</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" <td> 18173500</td>\n",
" <td> 15848300</td>\n",
" <td> 25416300</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" <td> 12492000</td>\n",
" <td> 10759700</td>\n",
" <td> 23108400</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" <td> 14839800</td>\n",
" <td> 15551500</td>\n",
" <td> 22434800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" <td> 20171900</td>\n",
" <td> 17008200</td>\n",
" <td> 27969100</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" <td> 16697300</td>\n",
" <td> 13448200</td>\n",
" <td> 26205800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 67,
"text": [
" price volume \n",
" AAPL JNJ SPX XOM AAPL JNJ XOM\n",
"2011-09-06 379.74 64.64 1165.24 71.15 18173500 15848300 25416300\n",
"2011-09-07 383.93 65.43 1198.62 73.65 12492000 10759700 23108400\n",
"2011-09-08 384.14 64.95 1185.90 72.82 14839800 15551500 22434800\n",
"2011-09-09 377.48 63.64 1154.23 71.01 20171900 17008200 27969100\n",
"2011-09-12 379.94 63.59 1162.27 71.84 16697300 13448200 26205800\n",
"2011-09-13 384.62 63.61 1172.87 71.65 NaN NaN NaN\n",
"2011-09-14 389.30 63.73 1188.68 72.64 NaN NaN NaN"
]
}
],
"prompt_number": 67
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.stack(0).unstack().dropna(axis=1, how='all')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"2\" halign=\"left\">AAPL</th>\n",
" <th colspan=\"2\" halign=\"left\">JNJ</th>\n",
" <th>SPX</th>\n",
" <th colspan=\"2\" halign=\"left\">XOM</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>price</th>\n",
" <th>volume</th>\n",
" <th>price</th>\n",
" <th>volume</th>\n",
" <th>price</th>\n",
" <th>price</th>\n",
" <th>volume</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 18173500</td>\n",
" <td> 64.64</td>\n",
" <td> 15848300</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" <td> 25416300</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 12492000</td>\n",
" <td> 65.43</td>\n",
" <td> 10759700</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" <td> 23108400</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 14839800</td>\n",
" <td> 64.95</td>\n",
" <td> 15551500</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" <td> 22434800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 20171900</td>\n",
" <td> 63.64</td>\n",
" <td> 17008200</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" <td> 27969100</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 16697300</td>\n",
" <td> 63.59</td>\n",
" <td> 13448200</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" <td> 26205800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> NaN</td>\n",
" <td> 63.61</td>\n",
" <td> NaN</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> NaN</td>\n",
" <td> 63.73</td>\n",
" <td> NaN</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 68,
"text": [
" AAPL JNJ SPX XOM \n",
" price volume price volume price price volume\n",
"2011-09-06 379.74 18173500 64.64 15848300 1165.24 71.15 25416300\n",
"2011-09-07 383.93 12492000 65.43 10759700 1198.62 73.65 23108400\n",
"2011-09-08 384.14 14839800 64.95 15551500 1185.90 72.82 22434800\n",
"2011-09-09 377.48 20171900 63.64 17008200 1154.23 71.01 27969100\n",
"2011-09-12 379.94 16697300 63.59 13448200 1162.27 71.84 26205800\n",
"2011-09-13 384.62 NaN 63.61 NaN 1172.87 71.65 NaN\n",
"2011-09-14 389.30 NaN 63.73 NaN 1188.68 72.64 NaN"
]
}
],
"prompt_number": 68
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"4\" halign=\"left\">price</th>\n",
" <th colspan=\"3\" halign=\"left\">volume</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" <td> 18173500</td>\n",
" <td> 15848300</td>\n",
" <td> 25416300</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" <td> 12492000</td>\n",
" <td> 10759700</td>\n",
" <td> 23108400</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" <td> 14839800</td>\n",
" <td> 15551500</td>\n",
" <td> 22434800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" <td> 20171900</td>\n",
" <td> 17008200</td>\n",
" <td> 27969100</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" <td> 16697300</td>\n",
" <td> 13448200</td>\n",
" <td> 26205800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 69,
"text": [
" price volume \n",
" AAPL JNJ SPX XOM AAPL JNJ XOM\n",
"2011-09-06 379.74 64.64 1165.24 71.15 18173500 15848300 25416300\n",
"2011-09-07 383.93 65.43 1198.62 73.65 12492000 10759700 23108400\n",
"2011-09-08 384.14 64.95 1185.90 72.82 14839800 15551500 22434800\n",
"2011-09-09 377.48 63.64 1154.23 71.01 20171900 17008200 27969100\n",
"2011-09-12 379.94 63.59 1162.27 71.84 16697300 13448200 26205800\n",
"2011-09-13 384.62 63.61 1172.87 71.65 NaN NaN NaN\n",
"2011-09-14 389.30 63.73 1188.68 72.64 NaN NaN NaN"
]
}
],
"prompt_number": 69
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df2 = pd.concat([prices, volume], axis=1, keys=['price', 'volume'])\n",
"df2\n",
"# df2.stack(0)\n",
"#df2.xs('AAPL', level=1, axis=1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"4\" halign=\"left\">price</th>\n",
" <th colspan=\"3\" halign=\"left\">volume</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2011-09-06</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" <td> 18173500</td>\n",
" <td> 15848300</td>\n",
" <td> 25416300</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-07</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" <td> 12492000</td>\n",
" <td> 10759700</td>\n",
" <td> 23108400</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-08</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" <td> 14839800</td>\n",
" <td> 15551500</td>\n",
" <td> 22434800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-09</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" <td> 20171900</td>\n",
" <td> 17008200</td>\n",
" <td> 27969100</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-12</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" <td> 16697300</td>\n",
" <td> 13448200</td>\n",
" <td> 26205800</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" <td> NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 70,
"text": [
" price volume \n",
" AAPL JNJ SPX XOM AAPL JNJ XOM\n",
"2011-09-06 379.74 64.64 1165.24 71.15 18173500 15848300 25416300\n",
"2011-09-07 383.93 65.43 1198.62 73.65 12492000 10759700 23108400\n",
"2011-09-08 384.14 64.95 1185.90 72.82 14839800 15551500 22434800\n",
"2011-09-09 377.48 63.64 1154.23 71.01 20171900 17008200 27969100\n",
"2011-09-12 379.94 63.59 1162.27 71.84 16697300 13448200 26205800\n",
"2011-09-13 384.62 63.61 1172.87 71.65 NaN NaN NaN\n",
"2011-09-14 389.30 63.73 1188.68 72.64 NaN NaN NaN"
]
}
],
"prompt_number": 70
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 70
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df2.stack(0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th>AAPL</th>\n",
" <th>JNJ</th>\n",
" <th>SPX</th>\n",
" <th>XOM</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td rowspan=\"2\" valign=\"top\"><strong>2011-09-06</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 379.74</td>\n",
" <td> 64.64</td>\n",
" <td> 1165.24</td>\n",
" <td> 71.15</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>volume</strong></td>\n",
" <td> 18173500.00</td>\n",
" <td> 15848300.00</td>\n",
" <td> NaN</td>\n",
" <td> 25416300.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"2\" valign=\"top\"><strong>2011-09-07</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 383.93</td>\n",
" <td> 65.43</td>\n",
" <td> 1198.62</td>\n",
" <td> 73.65</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>volume</strong></td>\n",
" <td> 12492000.00</td>\n",
" <td> 10759700.00</td>\n",
" <td> NaN</td>\n",
" <td> 23108400.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"2\" valign=\"top\"><strong>2011-09-08</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 384.14</td>\n",
" <td> 64.95</td>\n",
" <td> 1185.90</td>\n",
" <td> 72.82</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>volume</strong></td>\n",
" <td> 14839800.00</td>\n",
" <td> 15551500.00</td>\n",
" <td> NaN</td>\n",
" <td> 22434800.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"2\" valign=\"top\"><strong>2011-09-09</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 377.48</td>\n",
" <td> 63.64</td>\n",
" <td> 1154.23</td>\n",
" <td> 71.01</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>volume</strong></td>\n",
" <td> 20171900.00</td>\n",
" <td> 17008200.00</td>\n",
" <td> NaN</td>\n",
" <td> 27969100.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"2\" valign=\"top\"><strong>2011-09-12</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 379.94</td>\n",
" <td> 63.59</td>\n",
" <td> 1162.27</td>\n",
" <td> 71.84</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>volume</strong></td>\n",
" <td> 16697300.00</td>\n",
" <td> 13448200.00</td>\n",
" <td> NaN</td>\n",
" <td> 26205800.00</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-13</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 384.62</td>\n",
" <td> 63.61</td>\n",
" <td> 1172.87</td>\n",
" <td> 71.65</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2011-09-14</strong></td>\n",
" <td><strong>price</strong></td>\n",
" <td> 389.30</td>\n",
" <td> 63.73</td>\n",
" <td> 1188.68</td>\n",
" <td> 72.64</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 71,
"text": [
" AAPL JNJ SPX XOM\n",
"2011-09-06 price 379.74 64.64 1165.24 71.15\n",
" volume 18173500.00 15848300.00 NaN 25416300.00\n",
"2011-09-07 price 383.93 65.43 1198.62 73.65\n",
" volume 12492000.00 10759700.00 NaN 23108400.00\n",
"2011-09-08 price 384.14 64.95 1185.90 72.82\n",
" volume 14839800.00 15551500.00 NaN 22434800.00\n",
"2011-09-09 price 377.48 63.64 1154.23 71.01\n",
" volume 20171900.00 17008200.00 NaN 27969100.00\n",
"2011-09-12 price 379.94 63.59 1162.27 71.84\n",
" volume 16697300.00 13448200.00 NaN 26205800.00\n",
"2011-09-13 price 384.62 63.61 1172.87 71.65\n",
"2011-09-14 price 389.30 63.73 1188.68 72.64"
]
}
],
"prompt_number": 71
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vwap = (prices * volume).sum() / volume.sum()\n",
"vwap"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 72,
"text": [
"AAPL 380.655181\n",
"JNJ 64.394769\n",
"SPX NaN\n",
"XOM 72.024288"
]
}
],
"prompt_number": 72
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vwap.dropna()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 73,
"text": [
"AAPL 380.655181\n",
"JNJ 64.394769\n",
"XOM 72.024288"
]
}
],
"prompt_number": 73
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"prices.align(volume, join='inner')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 74,
"text": [
"( AAPL JNJ XOM\n",
"2011-09-06 379.74 64.64 71.15\n",
"2011-09-07 383.93 65.43 73.65\n",
"2011-09-08 384.14 64.95 72.82\n",
"2011-09-09 377.48 63.64 71.01\n",
"2011-09-12 379.94 63.59 71.84,\n",
" AAPL JNJ XOM\n",
"2011-09-06 18173500 15848300 25416300\n",
"2011-09-07 12492000 10759700 23108400\n",
"2011-09-08 14839800 15551500 22434800\n",
"2011-09-09 20171900 17008200 27969100\n",
"2011-09-12 16697300 13448200 26205800)"
]
}
],
"prompt_number": 74
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"s1 = Series(range(3), index=['a', 'b', 'c'])\n",
"s2 = Series(range(4), index=['d', 'b', 'c', 'e'])\n",
"s3 = Series(range(3), index=['f', 'a', 'c'])\n",
"side_by_side(s1, s2, s3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"a 0 d 0 f 0\n",
"b 1 b 1 a 1\n",
"c 2 c 2 c 2\n",
" e 3 \n"
]
}
],
"prompt_number": 75
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"DataFrame({'one': s1, 'two': s2, 'three': s3})"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>one</th>\n",
" <th>three</th>\n",
" <th>two</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>a</strong></td>\n",
" <td> 0</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>b</strong></td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>c</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>d</strong></td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>e</strong></td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td> 3</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>f</strong></td>\n",
" <td>NaN</td>\n",
" <td> 0</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 76,
"text": [
" one three two\n",
"a 0 1 NaN\n",
"b 1 NaN 1\n",
"c 2 2 2\n",
"d NaN NaN 0\n",
"e NaN NaN 3\n",
"f NaN 0 NaN"
]
}
],
"prompt_number": 76
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"DataFrame({'one': s1, 'two': s2, 'three': s3}, index=list('face'))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>one</th>\n",
" <th>three</th>\n",
" <th>two</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>f</strong></td>\n",
" <td>NaN</td>\n",
" <td> 0</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>a</strong></td>\n",
" <td> 0</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>c</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>e</strong></td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td> 3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 77,
"text": [
" one three two\n",
"f NaN 0 NaN\n",
"a 0 1 NaN\n",
"c 2 2 2\n",
"e NaN NaN 3"
]
}
],
"prompt_number": 77
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Time series different frequencies\n",
"-----"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts1 = Series(np.random.randn(3),\n",
" index=pd.date_range('2012-6-13', periods=3, freq='W-WED'))\n",
"ts1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 78,
"text": [
"2012-06-13 -0.696004\n",
"2012-06-20 0.337464\n",
"2012-06-27 0.537583\n",
"Freq: W-WED"
]
}
],
"prompt_number": 78
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 79,
"text": [
"2012-06-13 -0.696004\n",
"2012-06-20 0.337464\n",
"2012-06-27 0.537583\n",
"Freq: W-WED"
]
}
],
"prompt_number": 79
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts = Series(randn(1000000), index=pd.date_range('1/1/2000', periods=1000000, freq='S', tz='Europe/London'))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 80
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts.index.hour"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 81,
"text": [
"array([ 0, 0, 0, ..., 13, 13, 13], dtype=int32)"
]
}
],
"prompt_number": 81
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts.resample('M', how=['mean', 'std', 'first', 'last'])[:10]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>first</th>\n",
" <th>last</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2000-01-31</strong></td>\n",
" <td> 0.001613</td>\n",
" <td> 0.999271</td>\n",
" <td>-0.612053</td>\n",
" <td>-0.250134</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 82,
"text": [
" mean std first last\n",
"2000-01-31 0.001613 0.999271 -0.612053 -0.250134"
]
}
],
"prompt_number": 82
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts1.resample('B')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 83,
"text": [
"2012-06-13 -0.696004\n",
"2012-06-14 NaN\n",
"2012-06-15 NaN\n",
"2012-06-18 NaN\n",
"2012-06-19 NaN\n",
"2012-06-20 0.337464\n",
"2012-06-21 NaN\n",
"2012-06-22 NaN\n",
"2012-06-25 NaN\n",
"2012-06-26 NaN\n",
"2012-06-27 0.537583\n",
"Freq: B"
]
}
],
"prompt_number": 83
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts1.resample('B', fill_method='ffill')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 84,
"text": [
"2012-06-13 -0.696004\n",
"2012-06-14 -0.696004\n",
"2012-06-15 -0.696004\n",
"2012-06-18 -0.696004\n",
"2012-06-19 -0.696004\n",
"2012-06-20 0.337464\n",
"2012-06-21 0.337464\n",
"2012-06-22 0.337464\n",
"2012-06-25 0.337464\n",
"2012-06-26 0.337464\n",
"2012-06-27 0.537583\n",
"Freq: B"
]
}
],
"prompt_number": 84
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dates = pd.DatetimeIndex(['2012-6-12', '2012-6-17', '2012-6-18',\n",
" '2012-6-21', '2012-6-22', '2012-6-29'])\n",
"ts2 = Series(np.random.randn(6), index=dates)\n",
"ts2"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 85,
"text": [
"2012-06-12 1.772663\n",
"2012-06-17 -1.259435\n",
"2012-06-18 1.303441\n",
"2012-06-21 0.816256\n",
"2012-06-22 1.131010\n",
"2012-06-29 -0.405234"
]
}
],
"prompt_number": 85
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts1.reindex(ts2.index, method='ffill')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 86,
"text": [
"2012-06-12 NaN\n",
"2012-06-17 -0.696004\n",
"2012-06-18 -0.696004\n",
"2012-06-21 0.337464\n",
"2012-06-22 0.337464\n",
"2012-06-29 0.537583"
]
}
],
"prompt_number": 86
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts2 + ts1.reindex(ts2.index, method='ffill')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 87,
"text": [
"2012-06-12 NaN\n",
"2012-06-17 -1.955439\n",
"2012-06-18 0.607437\n",
"2012-06-21 1.153720\n",
"2012-06-22 1.468474\n",
"2012-06-29 0.132349"
]
}
],
"prompt_number": 87
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Periods\n",
"----"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"gdp = Series([1.78, 1.94, 2.08, 2.01, 2.15, 2.31, 2.46],\n",
" index=pd.period_range('1984Q2', periods=7, freq='Q-SEP'))\n",
"infl = Series([0.025, 0.045, 0.037, 0.04],\n",
" index=pd.period_range('1982', periods=4, freq='A-DEC'))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 88
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"Series(prices.ix[0].to_dict())"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 89,
"text": [
"AAPL 379.74\n",
"JNJ 64.64\n",
"SPX 1165.24\n",
"XOM 71.15"
]
}
],
"prompt_number": 89
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"gdp.index[0].asfreq('B', 'start')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 90,
"text": [
"Period('1984-01-02', 'B')"
]
}
],
"prompt_number": 90
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"side_by_side(gdp, infl)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1984Q2 1.78 1982 0.025\n",
"1984Q3 1.94 1983 0.045\n",
"1984Q4 2.08 1984 0.037\n",
"1985Q1 2.01 1985 0.040\n",
"1985Q2 2.15 Freq: A-DEC \n",
"1985Q3 2.31 \n",
"1985Q4 2.46 \n",
"Freq: Q-SEP \n"
]
}
],
"prompt_number": 91
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"infl_q = infl.asfreq('Q-SEP', how='end')\n",
"infl_q"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 92,
"text": [
"1983Q1 0.025\n",
"1984Q1 0.045\n",
"1985Q1 0.037\n",
"1986Q1 0.040\n",
"Freq: Q-SEP"
]
}
],
"prompt_number": 92
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"infl_q.reindex(gdp.index, method='ffill')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 93,
"text": [
"1984Q2 0.045\n",
"1984Q3 0.045\n",
"1984Q4 0.045\n",
"1985Q1 0.037\n",
"1985Q2 0.037\n",
"1985Q3 0.037\n",
"1985Q4 0.037\n",
"Freq: Q-SEP"
]
}
],
"prompt_number": 93
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Time of day selection, resampling\n",
"-----"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Make an intraday date range and time series\n",
"rng = pd.date_range('2012-06-01 09:30', '2012-06-01 15:59', freq='T')\n",
"# Make a 5-day series of 9:30-15:59 values\n",
"rng = rng.append([rng + pd.offsets.BDay(i) for i in range(1, 4)])\n",
"ts = Series(np.arange(len(rng), dtype=float), index=rng)\n",
"ts"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 94,
"text": [
"2012-06-01 09:30:00 0\n",
"2012-06-01 09:31:00 1\n",
"2012-06-01 09:32:00 2\n",
"2012-06-01 09:33:00 3\n",
"2012-06-01 09:34:00 4\n",
"2012-06-01 09:35:00 5\n",
"2012-06-01 09:36:00 6\n",
"2012-06-01 09:37:00 7\n",
"2012-06-01 09:38:00 8\n",
"2012-06-01 09:39:00 9\n",
"2012-06-01 09:40:00 10\n",
"2012-06-01 09:41:00 11\n",
"2012-06-01 09:42:00 12\n",
"2012-06-01 09:43:00 13\n",
"2012-06-01 09:44:00 14\n",
"...\n",
"2012-06-06 15:45:00 1545\n",
"2012-06-06 15:46:00 1546\n",
"2012-06-06 15:47:00 1547\n",
"2012-06-06 15:48:00 1548\n",
"2012-06-06 15:49:00 1549\n",
"2012-06-06 15:50:00 1550\n",
"2012-06-06 15:51:00 1551\n",
"2012-06-06 15:52:00 1552\n",
"2012-06-06 15:53:00 1553\n",
"2012-06-06 15:54:00 1554\n",
"2012-06-06 15:55:00 1555\n",
"2012-06-06 15:56:00 1556\n",
"2012-06-06 15:57:00 1557\n",
"2012-06-06 15:58:00 1558\n",
"2012-06-06 15:59:00 1559\n",
"Length: 1560"
]
}
],
"prompt_number": 94
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from datetime import time\n",
"ts[time(10)]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 95,
"text": [
"2012-06-01 10:00:00 30\n",
"2012-06-04 10:00:00 420\n",
"2012-06-05 10:00:00 810\n",
"2012-06-06 10:00:00 1200"
]
}
],
"prompt_number": 95
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts.between_time(time(10), time(10, 5))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 96,
"text": [
"2012-06-01 10:00:00 30\n",
"2012-06-01 10:01:00 31\n",
"2012-06-01 10:02:00 32\n",
"2012-06-01 10:03:00 33\n",
"2012-06-01 10:04:00 34\n",
"2012-06-01 10:05:00 35\n",
"2012-06-04 10:00:00 420\n",
"2012-06-04 10:01:00 421\n",
"2012-06-04 10:02:00 422\n",
"2012-06-04 10:03:00 423\n",
"2012-06-04 10:04:00 424\n",
"2012-06-04 10:05:00 425\n",
"2012-06-05 10:00:00 810\n",
"2012-06-05 10:01:00 811\n",
"2012-06-05 10:02:00 812\n",
"2012-06-05 10:03:00 813\n",
"2012-06-05 10:04:00 814\n",
"2012-06-05 10:05:00 815\n",
"2012-06-06 10:00:00 1200\n",
"2012-06-06 10:01:00 1201\n",
"2012-06-06 10:02:00 1202\n",
"2012-06-06 10:03:00 1203\n",
"2012-06-06 10:04:00 1204\n",
"2012-06-06 10:05:00 1205"
]
}
],
"prompt_number": 96
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts.resample('5min', how='sum')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 97,
"text": [
"2012-06-01 09:30:00 0\n",
"2012-06-01 09:35:00 15\n",
"2012-06-01 09:40:00 40\n",
"2012-06-01 09:45:00 65\n",
"2012-06-01 09:50:00 90\n",
"2012-06-01 09:55:00 115\n",
"2012-06-01 10:00:00 140\n",
"2012-06-01 10:05:00 165\n",
"2012-06-01 10:10:00 190\n",
"2012-06-01 10:15:00 215\n",
"2012-06-01 10:20:00 240\n",
"2012-06-01 10:25:00 265\n",
"2012-06-01 10:30:00 290\n",
"2012-06-01 10:35:00 315\n",
"2012-06-01 10:40:00 340\n",
"...\n",
"2012-06-06 14:50:00 7440\n",
"2012-06-06 14:55:00 7465\n",
"2012-06-06 15:00:00 7490\n",
"2012-06-06 15:05:00 7515\n",
"2012-06-06 15:10:00 7540\n",
"2012-06-06 15:15:00 7565\n",
"2012-06-06 15:20:00 7590\n",
"2012-06-06 15:25:00 7615\n",
"2012-06-06 15:30:00 7640\n",
"2012-06-06 15:35:00 7665\n",
"2012-06-06 15:40:00 7690\n",
"2012-06-06 15:45:00 7715\n",
"2012-06-06 15:50:00 7740\n",
"2012-06-06 15:55:00 7765\n",
"2012-06-06 16:00:00 6230\n",
"Freq: 5T, Length: 1519"
]
}
],
"prompt_number": 97
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ts.resample('5min', how=['first', 'max', 'min', 'last']).head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>first</th>\n",
" <th>max</th>\n",
" <th>min</th>\n",
" <th>last</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2012-06-01 09:30:00</strong></td>\n",
" <td> 0</td>\n",
" <td> 0</td>\n",
" <td> 0</td>\n",
" <td> 0</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-01 09:35:00</strong></td>\n",
" <td> 1</td>\n",
" <td> 5</td>\n",
" <td> 1</td>\n",
" <td> 5</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-01 09:40:00</strong></td>\n",
" <td> 6</td>\n",
" <td> 10</td>\n",
" <td> 6</td>\n",
" <td> 10</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-01 09:45:00</strong></td>\n",
" <td> 11</td>\n",
" <td> 15</td>\n",
" <td> 11</td>\n",
" <td> 15</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-01 09:50:00</strong></td>\n",
" <td> 16</td>\n",
" <td> 20</td>\n",
" <td> 16</td>\n",
" <td> 20</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 98,
"text": [
" first max min last\n",
"2012-06-01 09:30:00 0 0 0 0\n",
"2012-06-01 09:35:00 1 5 1 5\n",
"2012-06-01 09:40:00 6 10 6 10\n",
"2012-06-01 09:45:00 11 15 11 15\n",
"2012-06-01 09:50:00 16 20 16 20"
]
}
],
"prompt_number": 98
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# As of selection\n",
"indexer = np.sort(np.random.permutation(len(ts))[700:])\n",
"irr_ts = ts.copy()\n",
"irr_ts[indexer] = np.nan\n",
"irr_ts['2012-06-01 09:50':'2012-06-01 10:00']"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 99,
"text": [
"2012-06-01 09:50:00 20\n",
"2012-06-01 09:51:00 21\n",
"2012-06-01 09:52:00 NaN\n",
"2012-06-01 09:53:00 23\n",
"2012-06-01 09:54:00 24\n",
"2012-06-01 09:55:00 NaN\n",
"2012-06-01 09:56:00 NaN\n",
"2012-06-01 09:57:00 NaN\n",
"2012-06-01 09:58:00 28\n",
"2012-06-01 09:59:00 NaN\n",
"2012-06-01 10:00:00 NaN"
]
}
],
"prompt_number": 99
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"selection = pd.date_range('2012-06-01 10:00', periods=4, freq='B')\n",
"irr_ts.asof(selection)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 100,
"text": [
"2012-06-01 10:00:00 28\n",
"2012-06-04 10:00:00 420\n",
"2012-06-05 10:00:00 810\n",
"2012-06-06 10:00:00 1198\n",
"Freq: B"
]
}
],
"prompt_number": 100
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Splicing together sources\n",
"-------"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"data1 = DataFrame(np.ones((6, 3), dtype=float),\n",
" columns=['a', 'b', 'c'],\n",
" index=pd.date_range('6/12/2012', periods=6))\n",
"data2 = DataFrame(np.ones((6, 3), dtype=float) * 2,\n",
" columns=['a', 'b', 'c'],\n",
" index=pd.date_range('6/13/2012', periods=6))\n",
"spliced = pd.concat([data1.ix[:'2012-06-14'], data2.ix['2012-06-15':]])\n",
"spliced"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>a</th>\n",
" <th>b</th>\n",
" <th>c</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2012-06-12</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-13</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-14</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-15</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-16</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-17</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-18</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 101,
"text": [
" a b c\n",
"2012-06-12 1 1 1\n",
"2012-06-13 1 1 1\n",
"2012-06-14 1 1 1\n",
"2012-06-15 2 2 2\n",
"2012-06-16 2 2 2\n",
"2012-06-17 2 2 2\n",
"2012-06-18 2 2 2"
]
}
],
"prompt_number": 101
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"data2 = DataFrame(np.ones((6, 4), dtype=float) * 2,\n",
" columns=['a', 'b', 'c', 'd'],\n",
" index=pd.date_range('6/13/2012', periods=6))\n",
"spliced = pd.concat([data1.ix[:'2012-06-14'], data2.ix['2012-06-15':]])\n",
"spliced"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>a</th>\n",
" <th>b</th>\n",
" <th>c</th>\n",
" <th>d</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2012-06-12</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-13</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-14</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-15</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-16</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-17</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-18</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 102,
"text": [
" a b c d\n",
"2012-06-12 1 1 1 NaN\n",
"2012-06-13 1 1 1 NaN\n",
"2012-06-14 1 1 1 NaN\n",
"2012-06-15 2 2 2 2\n",
"2012-06-16 2 2 2 2\n",
"2012-06-17 2 2 2 2\n",
"2012-06-18 2 2 2 2"
]
}
],
"prompt_number": 102
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spliced_filled = spliced.combine_first(data2)\n",
"spliced_filled"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>a</th>\n",
" <th>b</th>\n",
" <th>c</th>\n",
" <th>d</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2012-06-12</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-13</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-14</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-15</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-16</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-17</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-18</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 103,
"text": [
" a b c d\n",
"2012-06-12 1 1 1 NaN\n",
"2012-06-13 1 1 1 2\n",
"2012-06-14 1 1 1 2\n",
"2012-06-15 2 2 2 2\n",
"2012-06-16 2 2 2 2\n",
"2012-06-17 2 2 2 2\n",
"2012-06-18 2 2 2 2"
]
}
],
"prompt_number": 103
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"side_by_side(spliced, data2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
" a b c d a b c d\n",
"2012-06-12 1 1 1 NaN 2012-06-13 2 2 2 2\n",
"2012-06-13 1 1 1 NaN 2012-06-14 2 2 2 2\n",
"2012-06-14 1 1 1 NaN 2012-06-15 2 2 2 2\n",
"2012-06-15 2 2 2 2 2012-06-16 2 2 2 2\n",
"2012-06-16 2 2 2 2 2012-06-17 2 2 2 2\n",
"2012-06-17 2 2 2 2 2012-06-18 2 2 2 2\n",
"2012-06-18 2 2 2 2 \n"
]
}
],
"prompt_number": 104
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spliced.update(data2, overwrite=False)\n",
"spliced"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>a</th>\n",
" <th>b</th>\n",
" <th>c</th>\n",
" <th>d</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2012-06-12</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-13</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-14</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-15</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-16</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-17</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-18</strong></td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 105,
"text": [
" a b c d\n",
"2012-06-12 1 1 1 NaN\n",
"2012-06-13 1 1 1 2\n",
"2012-06-14 1 1 1 2\n",
"2012-06-15 2 2 2 2\n",
"2012-06-16 2 2 2 2\n",
"2012-06-17 2 2 2 2\n",
"2012-06-18 2 2 2 2"
]
}
],
"prompt_number": 105
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"cp_spliced = spliced.copy()\n",
"cp_spliced[['a', 'c']] = data1[['a', 'c']]\n",
"cp_spliced"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>a</th>\n",
" <th>b</th>\n",
" <th>c</th>\n",
" <th>d</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>2012-06-12</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-13</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-14</strong></td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-15</strong></td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-16</strong></td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-17</strong></td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" <td> 1</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>2012-06-18</strong></td>\n",
" <td>NaN</td>\n",
" <td> 2</td>\n",
" <td>NaN</td>\n",
" <td> 2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 106,
"text": [
" a b c d\n",
"2012-06-12 1 1 1 NaN\n",
"2012-06-13 1 1 1 2\n",
"2012-06-14 1 1 1 2\n",
"2012-06-15 1 2 1 2\n",
"2012-06-16 1 2 1 2\n",
"2012-06-17 1 2 1 2\n",
"2012-06-18 NaN 2 NaN 2"
]
}
],
"prompt_number": 106
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Group analysis\n",
"-----"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import random; random.seed(0)\n",
"import string\n",
"\n",
"N = 1000\n",
"def rands(n):\n",
" choices = string.ascii_uppercase\n",
" return ''.join([random.choice(choices) for _ in xrange(n)])\n",
"tickers = np.array([rands(5) for _ in xrange(N)])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 107
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"M = 500\n",
"df = DataFrame({'Momentum' : np.random.randn(M) / 200 + 0.03,\n",
" 'Value' : np.random.randn(M) / 200 + 0.08,\n",
" 'ShortInterest' : np.random.randn(M) / 200 - 0.02},\n",
" index=tickers[:M])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 108
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Momentum</th>\n",
" <th>ShortInterest</th>\n",
" <th>Value</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>VTKGN</strong></td>\n",
" <td> 0.025646</td>\n",
" <td>-0.004996</td>\n",
" <td> 0.077454</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>KUHMP</strong></td>\n",
" <td> 0.023436</td>\n",
" <td>-0.015562</td>\n",
" <td> 0.089499</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>XNHTQ</strong></td>\n",
" <td> 0.025458</td>\n",
" <td>-0.026015</td>\n",
" <td> 0.080202</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>GXZVX</strong></td>\n",
" <td> 0.030264</td>\n",
" <td>-0.024858</td>\n",
" <td> 0.075108</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ISXRM</strong></td>\n",
" <td> 0.024114</td>\n",
" <td>-0.018324</td>\n",
" <td> 0.085960</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 109,
"text": [
" Momentum ShortInterest Value\n",
"VTKGN 0.025646 -0.004996 0.077454\n",
"KUHMP 0.023436 -0.015562 0.089499\n",
"XNHTQ 0.025458 -0.026015 0.080202\n",
"GXZVX 0.030264 -0.024858 0.075108\n",
"ISXRM 0.024114 -0.018324 0.085960"
]
}
],
"prompt_number": 109
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Momentum</th>\n",
" <th>ShortInterest</th>\n",
" <th>Value</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>VTKGN</strong></td>\n",
" <td> 0.025646</td>\n",
" <td>-0.004996</td>\n",
" <td> 0.077454</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>KUHMP</strong></td>\n",
" <td> 0.023436</td>\n",
" <td>-0.015562</td>\n",
" <td> 0.089499</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>XNHTQ</strong></td>\n",
" <td> 0.025458</td>\n",
" <td>-0.026015</td>\n",
" <td> 0.080202</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>GXZVX</strong></td>\n",
" <td> 0.030264</td>\n",
" <td>-0.024858</td>\n",
" <td> 0.075108</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ISXRM</strong></td>\n",
" <td> 0.024114</td>\n",
" <td>-0.018324</td>\n",
" <td> 0.085960</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 110,
"text": [
" Momentum ShortInterest Value\n",
"VTKGN 0.025646 -0.004996 0.077454\n",
"KUHMP 0.023436 -0.015562 0.089499\n",
"XNHTQ 0.025458 -0.026015 0.080202\n",
"GXZVX 0.030264 -0.024858 0.075108\n",
"ISXRM 0.024114 -0.018324 0.085960"
]
}
],
"prompt_number": 110
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ind_names = np.array(['FINANCIAL', 'TECH', 'CONSDUR'])\n",
"sampler = np.random.randint(0, len(ind_names), N)\n",
"industries = Series(ind_names[sampler], index=tickers,\n",
" name='industry')"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 111
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"industries"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 112,
"text": [
"VTKGN CONSDUR\n",
"KUHMP CONSDUR\n",
"XNHTQ FINANCIAL\n",
"GXZVX FINANCIAL\n",
"ISXRM FINANCIAL\n",
"CLPXZ TECH\n",
"MWGUO TECH\n",
"ASKVR CONSDUR\n",
"AMWGI CONSDUR\n",
"WEOGZ TECH\n",
"ULCIN FINANCIAL\n",
"YCOSO CONSDUR\n",
"VOZPP CONSDUR\n",
"LPKOH FINANCIAL\n",
"EEPRM CONSDUR\n",
"...\n",
"HEIZH CONSDUR\n",
"LWELG TECH\n",
"KYLBX TECH\n",
"WIBMQ FINANCIAL\n",
"LBCTN FINANCIAL\n",
"QHLIR FINANCIAL\n",
"LCRZK TECH\n",
"AOQJX CONSDUR\n",
"YMNLR CONSDUR\n",
"BHUFN TECH\n",
"FCKOG TECH\n",
"ILSDP FINANCIAL\n",
"PZPKM TECH\n",
"PNRHG CONSDUR\n",
"ZYTZZ TECH\n",
"Name: industry, Length: 1000"
]
}
],
"prompt_number": 112
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.describe()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Momentum</th>\n",
" <th>ShortInterest</th>\n",
" <th>Value</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>count</strong></td>\n",
" <td> 500.000000</td>\n",
" <td> 500.000000</td>\n",
" <td> 500.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>mean</strong></td>\n",
" <td> 0.029817</td>\n",
" <td> -0.019615</td>\n",
" <td> 0.080311</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>std</strong></td>\n",
" <td> 0.004901</td>\n",
" <td> 0.005024</td>\n",
" <td> 0.004813</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>min</strong></td>\n",
" <td> 0.015813</td>\n",
" <td> -0.036326</td>\n",
" <td> 0.067599</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>25%</strong></td>\n",
" <td> 0.026431</td>\n",
" <td> -0.023025</td>\n",
" <td> 0.076955</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>50%</strong></td>\n",
" <td> 0.030041</td>\n",
" <td> -0.019712</td>\n",
" <td> 0.080237</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>75%</strong></td>\n",
" <td> 0.033020</td>\n",
" <td> -0.016330</td>\n",
" <td> 0.083583</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>max</strong></td>\n",
" <td> 0.043649</td>\n",
" <td> -0.004012</td>\n",
" <td> 0.092778</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 113,
"text": [
" Momentum ShortInterest Value\n",
"count 500.000000 500.000000 500.000000\n",
"mean 0.029817 -0.019615 0.080311\n",
"std 0.004901 0.005024 0.004813\n",
"min 0.015813 -0.036326 0.067599\n",
"25% 0.026431 -0.023025 0.076955\n",
"50% 0.030041 -0.019712 0.080237\n",
"75% 0.033020 -0.016330 0.083583\n",
"max 0.043649 -0.004012 0.092778"
]
}
],
"prompt_number": 113
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grouped = df.groupby(industries)\n",
"grouped.describe().unstack('industry').stack(0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>industry</th>\n",
" <th>CONSDUR</th>\n",
" <th>FINANCIAL</th>\n",
" <th>TECH</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>count</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 166.000000</td>\n",
" <td> 168.000000</td>\n",
" <td> 166.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> 166.000000</td>\n",
" <td> 168.000000</td>\n",
" <td> 166.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 166.000000</td>\n",
" <td> 168.000000</td>\n",
" <td> 166.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>mean</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.029795</td>\n",
" <td> 0.029733</td>\n",
" <td> 0.029924</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.019553</td>\n",
" <td> -0.019478</td>\n",
" <td> -0.019815</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.080124</td>\n",
" <td> 0.080391</td>\n",
" <td> 0.080419</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>std</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.004903</td>\n",
" <td> 0.004722</td>\n",
" <td> 0.005101</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> 0.005039</td>\n",
" <td> 0.004652</td>\n",
" <td> 0.005382</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.004553</td>\n",
" <td> 0.005012</td>\n",
" <td> 0.004882</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>min</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.016506</td>\n",
" <td> 0.016847</td>\n",
" <td> 0.015813</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.032738</td>\n",
" <td> -0.031887</td>\n",
" <td> -0.036326</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.067599</td>\n",
" <td> 0.068798</td>\n",
" <td> 0.068095</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>25%</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.026101</td>\n",
" <td> 0.026451</td>\n",
" <td> 0.026852</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.022780</td>\n",
" <td> -0.022588</td>\n",
" <td> -0.023273</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.077415</td>\n",
" <td> 0.076693</td>\n",
" <td> 0.077046</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>50%</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.029807</td>\n",
" <td> 0.029913</td>\n",
" <td> 0.030185</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.019712</td>\n",
" <td> -0.019698</td>\n",
" <td> -0.019729</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.079896</td>\n",
" <td> 0.080668</td>\n",
" <td> 0.080317</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>75%</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.033600</td>\n",
" <td> 0.032729</td>\n",
" <td> 0.032805</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.016011</td>\n",
" <td> -0.016654</td>\n",
" <td> -0.016471</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.083053</td>\n",
" <td> 0.083832</td>\n",
" <td> 0.084173</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>max</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.042065</td>\n",
" <td> 0.042410</td>\n",
" <td> 0.043649</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.004996</td>\n",
" <td> -0.004012</td>\n",
" <td> -0.004521</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.092778</td>\n",
" <td> 0.092282</td>\n",
" <td> 0.091385</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 114,
"text": [
"industry CONSDUR FINANCIAL TECH\n",
"count Momentum 166.000000 168.000000 166.000000\n",
" ShortInterest 166.000000 168.000000 166.000000\n",
" Value 166.000000 168.000000 166.000000\n",
"mean Momentum 0.029795 0.029733 0.029924\n",
" ShortInterest -0.019553 -0.019478 -0.019815\n",
" Value 0.080124 0.080391 0.080419\n",
"std Momentum 0.004903 0.004722 0.005101\n",
" ShortInterest 0.005039 0.004652 0.005382\n",
" Value 0.004553 0.005012 0.004882\n",
"min Momentum 0.016506 0.016847 0.015813\n",
" ShortInterest -0.032738 -0.031887 -0.036326\n",
" Value 0.067599 0.068798 0.068095\n",
"25% Momentum 0.026101 0.026451 0.026852\n",
" ShortInterest -0.022780 -0.022588 -0.023273\n",
" Value 0.077415 0.076693 0.077046\n",
"50% Momentum 0.029807 0.029913 0.030185\n",
" ShortInterest -0.019712 -0.019698 -0.019729\n",
" Value 0.079896 0.080668 0.080317\n",
"75% Momentum 0.033600 0.032729 0.032805\n",
" ShortInterest -0.016011 -0.016654 -0.016471\n",
" Value 0.083053 0.083832 0.084173\n",
"max Momentum 0.042065 0.042410 0.043649\n",
" ShortInterest -0.004996 -0.004012 -0.004521\n",
" Value 0.092778 0.092282 0.091385"
]
}
],
"prompt_number": 114
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"industries"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 115,
"text": [
"VTKGN CONSDUR\n",
"KUHMP CONSDUR\n",
"XNHTQ FINANCIAL\n",
"GXZVX FINANCIAL\n",
"ISXRM FINANCIAL\n",
"CLPXZ TECH\n",
"MWGUO TECH\n",
"ASKVR CONSDUR\n",
"AMWGI CONSDUR\n",
"WEOGZ TECH\n",
"ULCIN FINANCIAL\n",
"YCOSO CONSDUR\n",
"VOZPP CONSDUR\n",
"LPKOH FINANCIAL\n",
"EEPRM CONSDUR\n",
"...\n",
"HEIZH CONSDUR\n",
"LWELG TECH\n",
"KYLBX TECH\n",
"WIBMQ FINANCIAL\n",
"LBCTN FINANCIAL\n",
"QHLIR FINANCIAL\n",
"LCRZK TECH\n",
"AOQJX CONSDUR\n",
"YMNLR CONSDUR\n",
"BHUFN TECH\n",
"FCKOG TECH\n",
"ILSDP FINANCIAL\n",
"PZPKM TECH\n",
"PNRHG CONSDUR\n",
"ZYTZZ TECH\n",
"Name: industry, Length: 1000"
]
}
],
"prompt_number": 115
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df.describe()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Momentum</th>\n",
" <th>ShortInterest</th>\n",
" <th>Value</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>count</strong></td>\n",
" <td> 500.000000</td>\n",
" <td> 500.000000</td>\n",
" <td> 500.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>mean</strong></td>\n",
" <td> 0.029817</td>\n",
" <td> -0.019615</td>\n",
" <td> 0.080311</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>std</strong></td>\n",
" <td> 0.004901</td>\n",
" <td> 0.005024</td>\n",
" <td> 0.004813</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>min</strong></td>\n",
" <td> 0.015813</td>\n",
" <td> -0.036326</td>\n",
" <td> 0.067599</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>25%</strong></td>\n",
" <td> 0.026431</td>\n",
" <td> -0.023025</td>\n",
" <td> 0.076955</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>50%</strong></td>\n",
" <td> 0.030041</td>\n",
" <td> -0.019712</td>\n",
" <td> 0.080237</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>75%</strong></td>\n",
" <td> 0.033020</td>\n",
" <td> -0.016330</td>\n",
" <td> 0.083583</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>max</strong></td>\n",
" <td> 0.043649</td>\n",
" <td> -0.004012</td>\n",
" <td> 0.092778</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 116,
"text": [
" Momentum ShortInterest Value\n",
"count 500.000000 500.000000 500.000000\n",
"mean 0.029817 -0.019615 0.080311\n",
"std 0.004901 0.005024 0.004813\n",
"min 0.015813 -0.036326 0.067599\n",
"25% 0.026431 -0.023025 0.076955\n",
"50% 0.030041 -0.019712 0.080237\n",
"75% 0.033020 -0.016330 0.083583\n",
"max 0.043649 -0.004012 0.092778"
]
}
],
"prompt_number": 116
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"by_industry = df.groupby(industries)\n",
"by_industry.describe().stack().unstack('industry')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>industry</th>\n",
" <th>CONSDUR</th>\n",
" <th>FINANCIAL</th>\n",
" <th>TECH</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>count</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 166.000000</td>\n",
" <td> 168.000000</td>\n",
" <td> 166.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> 166.000000</td>\n",
" <td> 168.000000</td>\n",
" <td> 166.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 166.000000</td>\n",
" <td> 168.000000</td>\n",
" <td> 166.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>mean</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.029795</td>\n",
" <td> 0.029733</td>\n",
" <td> 0.029924</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.019553</td>\n",
" <td> -0.019478</td>\n",
" <td> -0.019815</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.080124</td>\n",
" <td> 0.080391</td>\n",
" <td> 0.080419</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>std</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.004903</td>\n",
" <td> 0.004722</td>\n",
" <td> 0.005101</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> 0.005039</td>\n",
" <td> 0.004652</td>\n",
" <td> 0.005382</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.004553</td>\n",
" <td> 0.005012</td>\n",
" <td> 0.004882</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>min</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.016506</td>\n",
" <td> 0.016847</td>\n",
" <td> 0.015813</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.032738</td>\n",
" <td> -0.031887</td>\n",
" <td> -0.036326</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.067599</td>\n",
" <td> 0.068798</td>\n",
" <td> 0.068095</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>25%</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.026101</td>\n",
" <td> 0.026451</td>\n",
" <td> 0.026852</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.022780</td>\n",
" <td> -0.022588</td>\n",
" <td> -0.023273</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.077415</td>\n",
" <td> 0.076693</td>\n",
" <td> 0.077046</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>50%</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.029807</td>\n",
" <td> 0.029913</td>\n",
" <td> 0.030185</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.019712</td>\n",
" <td> -0.019698</td>\n",
" <td> -0.019729</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.079896</td>\n",
" <td> 0.080668</td>\n",
" <td> 0.080317</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>75%</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.033600</td>\n",
" <td> 0.032729</td>\n",
" <td> 0.032805</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.016011</td>\n",
" <td> -0.016654</td>\n",
" <td> -0.016471</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.083053</td>\n",
" <td> 0.083832</td>\n",
" <td> 0.084173</td>\n",
" </tr>\n",
" <tr>\n",
" <td rowspan=\"3\" valign=\"top\"><strong>max</strong></td>\n",
" <td><strong>Momentum</strong></td>\n",
" <td> 0.042065</td>\n",
" <td> 0.042410</td>\n",
" <td> 0.043649</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ShortInterest</strong></td>\n",
" <td> -0.004996</td>\n",
" <td> -0.004012</td>\n",
" <td> -0.004521</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>Value</strong></td>\n",
" <td> 0.092778</td>\n",
" <td> 0.092282</td>\n",
" <td> 0.091385</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 117,
"text": [
"industry CONSDUR FINANCIAL TECH\n",
"count Momentum 166.000000 168.000000 166.000000\n",
" ShortInterest 166.000000 168.000000 166.000000\n",
" Value 166.000000 168.000000 166.000000\n",
"mean Momentum 0.029795 0.029733 0.029924\n",
" ShortInterest -0.019553 -0.019478 -0.019815\n",
" Value 0.080124 0.080391 0.080419\n",
"std Momentum 0.004903 0.004722 0.005101\n",
" ShortInterest 0.005039 0.004652 0.005382\n",
" Value 0.004553 0.005012 0.004882\n",
"min Momentum 0.016506 0.016847 0.015813\n",
" ShortInterest -0.032738 -0.031887 -0.036326\n",
" Value 0.067599 0.068798 0.068095\n",
"25% Momentum 0.026101 0.026451 0.026852\n",
" ShortInterest -0.022780 -0.022588 -0.023273\n",
" Value 0.077415 0.076693 0.077046\n",
"50% Momentum 0.029807 0.029913 0.030185\n",
" ShortInterest -0.019712 -0.019698 -0.019729\n",
" Value 0.079896 0.080668 0.080317\n",
"75% Momentum 0.033600 0.032729 0.032805\n",
" ShortInterest -0.016011 -0.016654 -0.016471\n",
" Value 0.083053 0.083832 0.084173\n",
"max Momentum 0.042065 0.042410 0.043649\n",
" ShortInterest -0.004996 -0.004012 -0.004521\n",
" Value 0.092778 0.092282 0.091385"
]
}
],
"prompt_number": 117
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Within-Industry Standardize\n",
"def zscore(group):\n",
" return (group - group.mean()) / group.std()\n",
"\n",
"df_stand = by_industry.apply(zscore)\n",
"df_stand"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 118,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Index: 500 entries, VTKGN to PTDQE\n",
"Data columns:\n",
"Momentum 500 non-null values\n",
"ShortInterest 500 non-null values\n",
"Value 500 non-null values\n",
"dtypes: float64(3)"
]
}
],
"prompt_number": 118
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df_stand.groupby(industries).agg(['mean', 'std'])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"2\" halign=\"left\">Momentum</th>\n",
" <th colspan=\"2\" halign=\"left\">ShortInterest</th>\n",
" <th colspan=\"2\" halign=\"left\">Value</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" </tr>\n",
" <tr>\n",
" <th>industry</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>CONSDUR</strong></td>\n",
" <td> 1.902866e-16</td>\n",
" <td> 1</td>\n",
" <td> 4.019542e-16</td>\n",
" <td> 1</td>\n",
" <td> 6.310213e-15</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>FINANCIAL</strong></td>\n",
" <td> 2.327503e-15</td>\n",
" <td> 1</td>\n",
" <td>-4.506977e-16</td>\n",
" <td> 1</td>\n",
" <td>-6.007100e-16</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>TECH</strong></td>\n",
" <td>-6.828540e-16</td>\n",
" <td> 1</td>\n",
" <td> 7.684616e-16</td>\n",
" <td> 1</td>\n",
" <td> 5.733031e-15</td>\n",
" <td> 1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 119,
"text": [
" Momentum ShortInterest Value \n",
" mean std mean std mean std\n",
"industry \n",
"CONSDUR 1.902866e-16 1 4.019542e-16 1 6.310213e-15 1\n",
"FINANCIAL 2.327503e-15 1 -4.506977e-16 1 -6.007100e-16 1\n",
"TECH -6.828540e-16 1 7.684616e-16 1 5.733031e-15 1"
]
}
],
"prompt_number": 119
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ind_rank = by_industry.rank(ascending=False)\n",
"ind_rank.groupby(industries).agg(['min', 'max'])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr>\n",
" <th></th>\n",
" <th colspan=\"2\" halign=\"left\">Momentum</th>\n",
" <th colspan=\"2\" halign=\"left\">ShortInterest</th>\n",
" <th colspan=\"2\" halign=\"left\">Value</th>\n",
" </tr>\n",
" <tr>\n",
" <th></th>\n",
" <th>min</th>\n",
" <th>max</th>\n",
" <th>min</th>\n",
" <th>max</th>\n",
" <th>min</th>\n",
" <th>max</th>\n",
" </tr>\n",
" <tr>\n",
" <th>industry</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>CONSDUR</strong></td>\n",
" <td> 1</td>\n",
" <td> 166</td>\n",
" <td> 1</td>\n",
" <td> 166</td>\n",
" <td> 1</td>\n",
" <td> 166</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>FINANCIAL</strong></td>\n",
" <td> 1</td>\n",
" <td> 168</td>\n",
" <td> 1</td>\n",
" <td> 168</td>\n",
" <td> 1</td>\n",
" <td> 168</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>TECH</strong></td>\n",
" <td> 1</td>\n",
" <td> 166</td>\n",
" <td> 1</td>\n",
" <td> 166</td>\n",
" <td> 1</td>\n",
" <td> 166</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 120,
"text": [
" Momentum ShortInterest Value \n",
" min max min max min max\n",
"industry \n",
"CONSDUR 1 166 1 166 1 166\n",
"FINANCIAL 1 168 1 168 1 168\n",
"TECH 1 166 1 166 1 166"
]
}
],
"prompt_number": 120
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Groupby: factor exposures\n",
"-----"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from numpy.random import rand\n",
"fac1, fac2, fac3 = np.random.rand(3, 1000)\n",
"\n",
"ticker_subset = tickers.take(np.random.permutation(N)[:1000])\n",
"\n",
"# Weighted sum of factors plus noise\n",
"port = Series(0.7 * fac1 - 1.2 * fac2 + 0.3 * fac3 + rand(1000),\n",
" index=ticker_subset)\n",
"\n",
"factors = DataFrame({'f1': fac1, 'f2': fac2, 'f3': fac3},\n",
" index=ticker_subset)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 121
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"factors"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 122,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Index: 1000 entries, MDAQQ to VYIXZ\n",
"Data columns:\n",
"f1 1000 non-null values\n",
"f2 1000 non-null values\n",
"f3 1000 non-null values\n",
"dtypes: float64(3)"
]
}
],
"prompt_number": 122
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 122
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 122
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"pd.ols(y=port, x=factors).beta"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 123,
"text": [
"f1 0.689396\n",
"f2 -1.236091\n",
"f3 0.300945\n",
"intercept 0.532833"
]
}
],
"prompt_number": 123
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"factors"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 124,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Index: 1000 entries, MDAQQ to VYIXZ\n",
"Data columns:\n",
"f1 1000 non-null values\n",
"f2 1000 non-null values\n",
"f3 1000 non-null values\n",
"dtypes: float64(3)"
]
}
],
"prompt_number": 124
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"factors.head()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>f1</th>\n",
" <th>f2</th>\n",
" <th>f3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td><strong>MDAQQ</strong></td>\n",
" <td> 0.458753</td>\n",
" <td> 0.520772</td>\n",
" <td> 0.537957</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>GSZXN</strong></td>\n",
" <td> 0.782004</td>\n",
" <td> 0.892646</td>\n",
" <td> 0.433876</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>VREAP</strong></td>\n",
" <td> 0.727739</td>\n",
" <td> 0.302438</td>\n",
" <td> 0.125859</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>WMIUT</strong></td>\n",
" <td> 0.958790</td>\n",
" <td> 0.538893</td>\n",
" <td> 0.191673</td>\n",
" </tr>\n",
" <tr>\n",
" <td><strong>ALRVH</strong></td>\n",
" <td> 0.199568</td>\n",
" <td> 0.163397</td>\n",
" <td> 0.068531</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"output_type": "pyout",
"prompt_number": 125,
"text": [
" f1 f2 f3\n",
"MDAQQ 0.458753 0.520772 0.537957\n",
"GSZXN 0.782004 0.892646 0.433876\n",
"VREAP 0.727739 0.302438 0.125859\n",
"WMIUT 0.958790 0.538893 0.191673\n",
"ALRVH 0.199568 0.163397 0.068531"
]
}
],
"prompt_number": 125
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"factors.corrwith(port)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 126,
"text": [
"f1 0.391915\n",
"f2 -0.707937\n",
"f3 0.162403"
]
}
],
"prompt_number": 126
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"pd.ols(y=port, x=factors).beta"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 127,
"text": [
"f1 0.689396\n",
"f2 -1.236091\n",
"f3 0.300945\n",
"intercept 0.532833"
]
}
],
"prompt_number": 127
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#import pandas.rpy.common as com\n",
"#tips = com.load_data('tips', 'reshape2')\n",
"#tips"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 128
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#factors.values"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 129
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#tips.pivot_table('tip', rows=['sex', 'day'], cols='time', aggfunc='mean')"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 130
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"industries"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 131,
"text": [
"VTKGN CONSDUR\n",
"KUHMP CONSDUR\n",
"XNHTQ FINANCIAL\n",
"GXZVX FINANCIAL\n",
"ISXRM FINANCIAL\n",
"CLPXZ TECH\n",
"MWGUO TECH\n",
"ASKVR CONSDUR\n",
"AMWGI CONSDUR\n",
"WEOGZ TECH\n",
"ULCIN FINANCIAL\n",
"YCOSO CONSDUR\n",
"VOZPP CONSDUR\n",
"LPKOH FINANCIAL\n",
"EEPRM CONSDUR\n",
"...\n",
"HEIZH CONSDUR\n",
"LWELG TECH\n",
"KYLBX TECH\n",
"WIBMQ FINANCIAL\n",
"LBCTN FINANCIAL\n",
"QHLIR FINANCIAL\n",
"LCRZK TECH\n",
"AOQJX CONSDUR\n",
"YMNLR CONSDUR\n",
"BHUFN TECH\n",
"FCKOG TECH\n",
"ILSDP FINANCIAL\n",
"PZPKM TECH\n",
"PNRHG CONSDUR\n",
"ZYTZZ TECH\n",
"Name: industry, Length: 1000"
]
}
],
"prompt_number": 131
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"port.groupby(industries).apply(beta_exposure, factors=factors).unstack('industry').plot(kind='barh')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'beta_exposure' is not defined",
"output_type": "pyerr",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-132-9858f53eed65>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mport\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindustries\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbeta_exposure\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfactors\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfactors\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munstack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'industry'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkind\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'barh'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'beta_exposure' is not defined"
]
}
],
"prompt_number": 132
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def beta_exposure(chunk, factors=None):\n",
" return pd.ols(y=chunk, x=factors).beta"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 133
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"by_ind = port.groupby(industries)\n",
"exposures = by_ind.apply(beta_exposure, factors=factors)\n",
"exposures\n",
"#exposures.unstack()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 134,
"text": [
"industry \n",
"CONSDUR f1 0.638321\n",
" f2 -1.229472\n",
" f3 0.344701\n",
" intercept 0.536628\n",
"FINANCIAL f1 0.733277\n",
" f2 -1.258941\n",
" f3 0.229833\n",
" intercept 0.548040\n",
"TECH f1 0.705644\n",
" f2 -1.209612\n",
" f3 0.311739\n",
" intercept 0.509615"
]
}
],
"prompt_number": 134
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import pandas.io.data as web\n",
"#data = web.get_data_yahoo('SPY', '2006-01-01')\n",
"data = pd.load('_spy_2006')\n",
"data\n",
"# data.save('_spy_2006')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 135,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"DatetimeIndex: 1709 entries, 2006-01-03 00:00:00 to 2012-10-12 00:00:00\n",
"Data columns:\n",
"Open 1709 non-null values\n",
"High 1709 non-null values\n",
"Low 1709 non-null values\n",
"Close 1709 non-null values\n",
"Volume 1709 non-null values\n",
"Adj Close 1709 non-null values\n",
"dtypes: float64(5), int64(1)"
]
}
],
"prompt_number": 135
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"px = data['Adj Close']\n",
"returns = px.pct_change()\n",
"\n",
"def to_index(rets):\n",
" index = (1 + rets).cumprod()\n",
" first_loc = max(index.notnull().argmax() - 1, 0)\n",
" index.values[first_loc] = 1\n",
" return index\n",
"\n",
"def trend_signal(rets, lookback, lag):\n",
" signal = pd.rolling_sum(rets, lookback, min_periods=lookback - 5)\n",
" return signal.shift(lag)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 136
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"signal = trend_signal(returns, 100, 3)\n",
"trade_friday = signal.resample('W-FRI').resample('B', fill_method='ffill')\n",
"trade_rets = trade_friday.shift(1) * returns"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 137
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"to_index(trade_rets).plot()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 138,
"text": [
"<matplotlib.axes.AxesSubplot at 0x110e8e890>"
]
},
{
"output_type": "display_data",
"png": "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\nSUVORK5CYII=\n"
}
],
"prompt_number": 138
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"vol = pd.rolling_std(returns, 250, min_periods=200) * np.sqrt(250)\n",
"def sharpe(rets, ann=250):\n",
" return rets.mean() / rets.std() * np.sqrt(ann)\n",
"vol"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 139,
"text": [
"Date\n",
"2006-01-03 NaN\n",
"2006-01-04 NaN\n",
"2006-01-05 NaN\n",
"2006-01-06 NaN\n",
"2006-01-09 NaN\n",
"2006-01-10 NaN\n",
"2006-01-11 NaN\n",
"2006-01-12 NaN\n",
"2006-01-13 NaN\n",
"2006-01-17 NaN\n",
"2006-01-18 NaN\n",
"2006-01-19 NaN\n",
"2006-01-20 NaN\n",
"2006-01-23 NaN\n",
"2006-01-24 NaN\n",
"...\n",
"2012-09-24 0.174691\n",
"2012-09-25 0.173758\n",
"2012-09-26 0.173749\n",
"2012-09-27 0.171981\n",
"2012-09-28 0.169503\n",
"2012-10-01 0.168241\n",
"2012-10-02 0.167331\n",
"2012-10-03 0.166482\n",
"2012-10-04 0.166412\n",
"2012-10-05 0.163207\n",
"2012-10-08 0.163265\n",
"2012-10-09 0.163430\n",
"2012-10-10 0.163565\n",
"2012-10-11 0.162745\n",
"2012-10-12 0.161573\n",
"Length: 1709"
]
}
],
"prompt_number": 139
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"cats = pd.qcut(vol, 4)\n",
"trade_rets.groupby(cats).agg(sharpe) # .agg([sharpe, len])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 140,
"text": [
"[0.0954, 0.162] 0.664116\n",
"(0.162, 0.188] 0.321207\n",
"(0.188, 0.231] -0.980406\n",
"(0.231, 0.457] 0.586623"
]
}
],
"prompt_number": 140
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Signal frontier analysis\n",
"------"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"px = pd.load('stock_prices')\n",
"px"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 141,
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"DatetimeIndex: 861 entries, 2009-01-02 00:00:00 to 2012-06-01 00:00:00\n",
"Data columns:\n",
"AAPL 861 non-null values\n",
"BAC 861 non-null values\n",
"C 861 non-null values\n",
"DELL 861 non-null values\n",
"GOOG 861 non-null values\n",
"GS 861 non-null values\n",
"MS 861 non-null values\n",
"MSFT 861 non-null values\n",
"dtypes: float64(8)"
]
}
],
"prompt_number": 141
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"px = px.asfreq('B').fillna(method='pad')\n",
"rets = px.pct_change()\n",
"#! figure,id=finance_stock_rets,width=4in,title=\"Cumulative returns for each of the stocks\"\n",
"((1 + rets).cumprod() - 1).plot()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 142,
"text": [
"<matplotlib.axes.AxesSubplot at 0x110b58f90>"
]
},
{
"output_type": "display_data",
"png": "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\n"
}
],
"prompt_number": 142
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def calc_mom(price, lookback, lag):\n",
" mom_ret = price.shift(lag).pct_change(lookback)\n",
" ranks = mom_ret.rank(axis=1, ascending=False)\n",
" demeaned = ranks - ranks.mean(axis=1)\n",
" return demeaned / demeaned.std(axis=1)\n",
"\n",
"compound = lambda x : (1 + x).prod() - 1\n",
"daily_sr = lambda x: x.mean() / x.std()\n",
"\n",
"def strat_sr(prices, lb, hold):\n",
" # Compute portfolio weights\n",
" freq = '%dB' % hold\n",
" port = calc_mom(prices, lb, lag=1)\n",
"\n",
" daily_rets = prices.pct_change()\n",
"\n",
" # Compute portfolio returns\n",
" port = port.shift(1).resample(freq, how='first')\n",
" returns = daily_rets.resample(freq, how=compound)\n",
" port_rets = (port * returns).sum(axis=1)\n",
"\n",
" return daily_sr(port_rets) * np.sqrt(252 / hold)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 143
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"strat_sr(px, 70, 30)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 144,
"text": [
"0.26760724612725928"
]
}
],
"prompt_number": 144
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from collections import defaultdict\n",
"\n",
"lookbacks = range(20, 90, 5)\n",
"holdings = range(20, 90, 5)\n",
"dd = defaultdict(dict)\n",
"for lb in lookbacks:\n",
" for hold in holdings:\n",
" dd[lb][hold] = strat_sr(px, lb, hold)\n",
"\n",
"ddf = DataFrame(dd)\n",
"ddf.index.name = 'Holding Period'\n",
"ddf.columns.name = 'Lookback Period'"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 145
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import matplotlib.pyplot as plt\n",
"\n",
"def heatmap(df, cmap=plt.cm.gray_r):\n",
" fig = plt.figure()\n",
" ax = fig.add_subplot(111)\n",
" axim = ax.imshow(df.values, cmap=cmap, interpolation='nearest')\n",
" ax.set_xlabel(df.columns.name)\n",
" ax.set_xticks(np.arange(len(df.columns)))\n",
" ax.set_xticklabels(list(df.columns))\n",
" ax.set_ylabel(df.index.name)\n",
" ax.set_yticks(np.arange(len(df.index)))\n",
" ax.set_yticklabels(list(df.index))\n",
" plt.colorbar(axim)\n",
"heatmap(ddf)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"png": "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\nWlFRgYkTJ2LcuHFYtGgRcnJyYGpqCh8fH8jlcrG6QAhpR/qS5PgQdUD1okWLcObMGWRmZuLjjz9G\nly5dsGPHDly8eBFZWVlYv3691qdBQq8ZCo2/fPmyoPjc3FxB8b/++mu7xALC9/23335r1/avXLnS\nrvGFhYXtGt9WDOmI0GBnligUinaNN+REKLRtoYng2rVrguKF/uyFXsMTGi80kd26dUtQfFsxpESo\n19VnCCGGS1+SHB96nQhbmyNobm7Oaw6htvG1tbVq41s7rVdXzqhr167cAHNljIyM1MZbWloq/Uzd\nHTh1bau7Y21ubo6+ffuq/NzU1LTVeAsLC1hbW6v8vGfPnmrbb+1nr+53161bN1hZWbX6HSHx5eXl\nrcb36NEDzz77rMrP1f3+evbsCTs7O5Wfjxo1qtX4oqIi9O/fX+lnXbt2xc8//9xqPF/6sh4JH6IN\nnxHKkP41IaSj0cXwGb569+6N4uJiQe0JpbeJkBBC2orhHLsSQohIKBESQjo9vU+EhYWFGDduHIYN\nGwY/Pz8kJiYC4F+2W1X8qlWrYGdnB6lUCqlUimPHjrWIraqqgpeXF9zd3eHt7Y0NGzZo1LaqeD5t\nN1VXVwepVIopU6Zo1L6qeE3ad3JywsiRIyGVSrm6bpq0ryxek/bLy8uxcOFCDBkyBK6urkhPT9eo\n/afj09LSeLd/5coV7jtSqRSWlpbYvHkzysrKeLWvLH7Tpk0a7b+ysvOa7L+yeE3//joFpueKiopY\ndnY2Y4yx+/fvswEDBrCSkhIWExPD/v73v7Oqqiq2ZMkStm7dOo3iV61axT777DO17ZeXlzPGGKuq\nqmLDhg1jV69e5d22qni+bTf67LPP2GuvvcamTJnCGGMata8sXpP2nZyc2MOHD5u9p0n7yuI1aT8y\nMpJFRUWxyspKVlNTwx49eqRR+8riNf35M8ZYXV0ds7GxYQUFBRr//J+O59v+w4cPmZOTEysrK2N1\ndXXs5ZdfZseOHePdvqp4bfa/o9P7I0IbGxu4u7sDAKysrDBs2DBkZmbyKtvdWjzA785Yt27dAABl\nZWWora2FmZkZ77ZVxfNtG2gYPHv06FG88cYbXIwm7SuLZ4xpdFfw6e9q0r6yeFXvKXPixAm8//77\n6Nq1K4yNjWFpaalR+8riNWm/6XYGDRoEe3t7jff/6Xi+P39lZed79erFu31V8drsf4fXDslXa3l5\n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\n"
}
],
"prompt_number": 146
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"rng = pd.date_range('2012-10-16 09:30:00', '2012-10-16 16:0:00', freq='t')\n",
"N = len(rng)\n",
"perm1 = np.random.permutation(N)[:N//2]\n",
"perm2 = np.random.permutation(N)[:N//2]\n",
"ts1 = Series(randn(N // 2), index=rng.take(perm1)).sort_index()\n",
"ts2 = Series(randn(N // 2), index=rng.take(perm2)).sort_index()\n",
"side_by_side(ts1, ts2)\n",
"ts1.reindex(ts2.index)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2012-10-16 09:33:00 1.161896 2012-10-16 09:32:00 -1.300346\n",
"2012-10-16 09:35:00 -0.424035 2012-10-16 09:34:00 0.737593\n",
"2012-10-16 09:38:00 0.096810 2012-10-16 09:35:00 1.518603\n",
"2012-10-16 09:40:00 -0.223288 2012-10-16 09:38:00 -0.206394\n",
"2012-10-16 09:42:00 -0.358402 2012-10-16 09:39:00 2.092389\n",
"2012-10-16 09:45:00 -1.968381 2012-10-16 09:40:00 -2.144698\n",
"2012-10-16 09:47:00 0.566090 2012-10-16 09:41:00 0.021480\n",
"2012-10-16 09:48:00 0.318876 2012-10-16 09:43:00 0.729408\n",
"2012-10-16 09:49:00 -0.319567 2012-10-16 09:44:00 -0.150988\n",
"2012-10-16 09:52:00 0.984125 2012-10-16 09:47:00 0.254694\n",
"2012-10-16 09:53:00 -0.363736 2012-10-16 09:48:00 0.370540\n",
"2012-10-16 09:57:00 0.143757 2012-10-16 09:50:00 0.633632\n",
"2012-10-16 10:00:00 -0.435288 2012-10-16 09:52:00 1.344515\n",
"2012-10-16 10:02:00 0.042154 2012-10-16 09:53:00 -0.230976\n",
"2012-10-16 10:05:00 0.460034 2012-10-16 09:54:00 0.217070\n",
"2012-10-16 10:06:00 -0.295201 2012-10-16 09:56:00 0.052677\n",
"2012-10-16 10:08:00 0.012224 2012-10-16 09:57:00 0.575831\n",
"2012-10-16 10:10:00 0.710831 2012-10-16 09:59:00 -0.886181\n",
"2012-10-16 10:12:00 -0.794603 2012-10-16 10:01:00 0.905115\n",
"2012-10-16 10:14:00 -2.032069 2012-10-16 10:03:00 0.066727\n",
"2012-10-16 10:15:00 -0.162541 2012-10-16 10:04:00 -0.659118\n",
"2012-10-16 10:16:00 0.410287 2012-10-16 10:05:00 0.893412\n",
"2012-10-16 10:17:00 -0.926198 2012-10-16 10:06:00 0.340830\n",
"2012-10-16 10:20:00 0.448870 2012-10-16 10:11:00 1.267284\n",
"2012-10-16 10:21:00 -1.110264 2012-10-16 10:13:00 -1.265216\n",
"2012-10-16 10:24:00 -0.418440 2012-10-16 10:14:00 -0.136740\n",
"2012-10-16 10:26:00 -1.702216 2012-10-16 10:15:00 -1.146660\n",
"2012-10-16 10:27:00 -0.417455 2012-10-16 10:17:00 2.441617\n",
"2012-10-16 10:28:00 -0.600131 2012-10-16 10:25:00 -1.892832\n",
"2012-10-16 10:30:00 -0.038478 2012-10-16 10:29:00 0.817336\n",
"2012-10-16 10:31:00 1.186224 2012-10-16 10:30:00 -0.496145\n",
"2012-10-16 10:32:00 -0.402476 2012-10-16 10:31:00 -0.021454\n",
"2012-10-16 10:38:00 -0.521280 2012-10-16 10:35:00 0.449048\n",
"2012-10-16 10:39:00 0.241372 2012-10-16 10:36:00 0.205820\n",
"2012-10-16 10:40:00 -0.061271 2012-10-16 10:37:00 0.405399\n",
"2012-10-16 10:41:00 0.739980 2012-10-16 10:38:00 -0.884954\n",
"2012-10-16 10:42:00 -0.458868 2012-10-16 10:41:00 1.144622\n",
"2012-10-16 10:47:00 0.905588 2012-10-16 10:45:00 -1.440385\n",
"2012-10-16 10:51:00 -0.004141 2012-10-16 10:46:00 -0.132815\n",
"2012-10-16 10:53:00 0.387685 2012-10-16 10:47:00 -1.509414\n",
"2012-10-16 10:54:00 1.375999 2012-10-16 10:48:00 1.433436\n",
"2012-10-16 11:03:00 1.259017 2012-10-16 10:50:00 -0.575359\n",
"2012-10-16 11:05:00 1.536359 2012-10-16 10:51:00 -0.681493\n",
"2012-10-16 11:06:00 -0.350725 2012-10-16 10:52:00 -0.782896\n",
"2012-10-16 11:11:00 -0.617283 2012-10-16 10:55:00 1.770291\n",
"2012-10-16 11:12:00 0.350695 2012-10-16 10:56:00 -0.638401\n",
"2012-10-16 11:14:00 0.010051 2012-10-16 10:57:00 -1.644768\n",
"2012-10-16 11:15:00 0.356945 2012-10-16 10:58:00 -0.681847\n",
"2012-10-16 11:17:00 0.500463 2012-10-16 11:00:00 0.314333\n",
"2012-10-16 11:25:00 -0.141152 2012-10-16 11:02:00 -2.278606\n",
"2012-10-16 11:27:00 0.922033 2012-10-16 11:05:00 1.033343\n",
"2012-10-16 11:28:00 -1.135601 2012-10-16 11:07:00 0.367647\n",
"2012-10-16 11:31:00 -0.748450 2012-10-16 11:11:00 0.030783\n",
"2012-10-16 11:32:00 1.071630 2012-10-16 11:19:00 1.193131\n",
"2012-10-16 11:34:00 0.683754 2012-10-16 11:20:00 0.055599\n",
"2012-10-16 11:37:00 0.123272 2012-10-16 11:21:00 -0.200509\n",
"2012-10-16 11:39:00 0.575960 2012-10-16 11:22:00 0.121410\n",
"2012-10-16 11:40:00 -0.375992 2012-10-16 11:23:00 0.983344\n",
"2012-10-16 11:42:00 -0.174095 2012-10-16 11:25:00 0.910896\n",
"2012-10-16 11:48:00 -0.988031 2012-10-16 11:26:00 -1.634392\n",
"2012-10-16 11:49:00 1.470663 2012-10-16 11:28:00 0.636063\n",
"2012-10-16 11:50:00 -0.255372 2012-10-16 11:31:00 0.008008\n",
"2012-10-16 11:51:00 0.602433 2012-10-16 11:32:00 0.296134\n",
"2012-10-16 11:52:00 -0.096405 2012-10-16 11:34:00 2.371591\n",
"2012-10-16 11:53:00 -0.409156 2012-10-16 11:35:00 0.104662\n",
"2012-10-16 11:55:00 0.044127 2012-10-16 11:37:00 -0.081337\n",
"2012-10-16 11:59:00 -0.689673 2012-10-16 11:39:00 0.632885\n",
"2012-10-16 12:05:00 0.757033 2012-10-16 11:40:00 1.042407\n",
"2012-10-16 12:06:00 -0.350098 2012-10-16 11:42:00 -0.113980\n",
"2012-10-16 12:07:00 0.883299 2012-10-16 11:44:00 -1.936668\n",
"2012-10-16 12:08:00 1.818434 2012-10-16 11:45:00 -0.518317\n",
"2012-10-16 12:09:00 -1.027395 2012-10-16 11:47:00 -0.436935\n",
"2012-10-16 12:12:00 0.859059 2012-10-16 11:49:00 0.134638\n",
"2012-10-16 12:17:00 1.791868 2012-10-16 11:55:00 1.157937\n",
"2012-10-16 12:18:00 3.109751 2012-10-16 12:04:00 0.345397\n",
"2012-10-16 12:20:00 1.876350 2012-10-16 12:05:00 1.486812\n",
"2012-10-16 12:21:00 1.081112 2012-10-16 12:08:00 0.957131\n",
"2012-10-16 12:23:00 -0.317728 2012-10-16 12:09:00 -1.525120\n",
"2012-10-16 12:24:00 0.608940 2012-10-16 12:10:00 -0.216439\n",
"2012-10-16 12:25:00 1.335344 2012-10-16 12:11:00 0.171334\n",
"2012-10-16 12:26:00 -0.086331 2012-10-16 12:14:00 1.649651\n",
"2012-10-16 12:27:00 0.456303 2012-10-16 12:15:00 0.816181\n",
"2012-10-16 12:29:00 1.129526 2012-10-16 12:20:00 -0.074992\n",
"2012-10-16 12:30:00 0.420770 2012-10-16 12:22:00 0.272746\n",
"2012-10-16 12:31:00 -2.019354 2012-10-16 12:25:00 1.115338\n",
"2012-10-16 12:32:00 1.180517 2012-10-16 12:32:00 0.298009\n",
"2012-10-16 12:33:00 0.102620 2012-10-16 12:34:00 0.173719\n",
"2012-10-16 12:35:00 0.517823 2012-10-16 12:35:00 0.168404\n",
"2012-10-16 12:36:00 -0.499363 2012-10-16 12:39:00 0.191305\n",
"2012-10-16 12:37:00 -0.293633 2012-10-16 12:41:00 0.733980\n",
"2012-10-16 12:43:00 0.333663 2012-10-16 12:43:00 -0.505093\n",
"2012-10-16 12:48:00 0.646847 2012-10-16 12:47:00 1.047919\n",
"2012-10-16 12:49:00 0.038483 2012-10-16 12:50:00 0.121055\n",
"2012-10-16 12:55:00 0.082751 2012-10-16 12:52:00 1.395637\n",
"2012-10-16 12:57:00 -0.395835 2012-10-16 12:54:00 0.140281\n",
"2012-10-16 12:58:00 1.370510 2012-10-16 12:55:00 0.532537\n",
"2012-10-16 12:59:00 -1.956925 2012-10-16 12:56:00 0.848052\n",
"2012-10-16 13:00:00 -0.849667 2012-10-16 12:57:00 -0.307925\n",
"2012-10-16 13:01:00 1.222593 2012-10-16 12:58:00 1.520089\n",
"2012-10-16 13:02:00 -0.445067 2012-10-16 12:59:00 -1.544447\n",
"2012-10-16 13:03:00 -1.440613 2012-10-16 13:01:00 0.438865\n",
"2012-10-16 13:04:00 0.932419 2012-10-16 13:02:00 -0.835241\n",
"2012-10-16 13:05:00 -0.230118 2012-10-16 13:03:00 -0.620983\n",
"2012-10-16 13:07:00 0.833799 2012-10-16 13:04:00 -0.531532\n",
"2012-10-16 13:08:00 0.744495 2012-10-16 13:06:00 0.808039\n",
"2012-10-16 13:09:00 0.484886 2012-10-16 13:08:00 -0.285458\n",
"2012-10-16 13:10:00 1.658537 2012-10-16 13:11:00 0.809177\n",
"2012-10-16 13:11:00 0.983593 2012-10-16 13:12:00 0.984205\n",
"2012-10-16 13:13:00 2.111926 2012-10-16 13:13:00 0.458377\n",
"2012-10-16 13:14:00 1.418948 2012-10-16 13:14:00 0.463013\n",
"2012-10-16 13:15:00 0.342722 2012-10-16 13:17:00 0.642729\n",
"2012-10-16 13:17:00 -0.009992 2012-10-16 13:18:00 0.946382\n",
"2012-10-16 13:19:00 -0.836433 2012-10-16 13:20:00 -0.992153\n",
"2012-10-16 13:21:00 1.285362 2012-10-16 13:21:00 -1.263370\n",
"2012-10-16 13:22:00 1.033943 2012-10-16 13:23:00 1.217248\n",
"2012-10-16 13:23:00 -0.988116 2012-10-16 13:24:00 0.101165\n",
"2012-10-16 13:25:00 -2.027632 2012-10-16 13:25:00 -0.851931\n",
"2012-10-16 13:28:00 -2.789475 2012-10-16 13:27:00 2.476545\n",
"2012-10-16 13:31:00 -0.027958 2012-10-16 13:28:00 -0.448301\n",
"2012-10-16 13:35:00 1.012843 2012-10-16 13:31:00 1.658249\n",
"2012-10-16 13:36:00 1.089322 2012-10-16 13:32:00 0.638995\n",
"2012-10-16 13:38:00 -0.660387 2012-10-16 13:33:00 0.594772\n",
"2012-10-16 13:39:00 0.351148 2012-10-16 13:34:00 0.102370\n",
"2012-10-16 13:40:00 -0.945711 2012-10-16 13:36:00 0.554731\n",
"2012-10-16 13:41:00 -0.563830 2012-10-16 13:37:00 0.048993\n",
"2012-10-16 13:45:00 -0.267201 2012-10-16 13:40:00 0.214773\n",
"2012-10-16 13:46:00 0.504712 2012-10-16 13:41:00 -0.292942\n",
"2012-10-16 13:48:00 -0.350050 2012-10-16 13:42:00 -0.200627\n",
"2012-10-16 13:56:00 -1.133351 2012-10-16 13:43:00 0.611994\n",
"2012-10-16 13:59:00 -0.745663 2012-10-16 13:46:00 -1.726171\n",
"2012-10-16 14:01:00 0.941548 2012-10-16 13:50:00 -1.461825\n",
"2012-10-16 14:02:00 -0.158871 2012-10-16 13:51:00 -0.554423\n",
"2012-10-16 14:03:00 0.898255 2012-10-16 13:54:00 -2.508451\n",
"2012-10-16 14:04:00 1.186308 2012-10-16 13:55:00 -1.297290\n",
"2012-10-16 14:05:00 0.211746 2012-10-16 13:56:00 -0.999784\n",
"2012-10-16 14:11:00 1.760259 2012-10-16 13:57:00 1.224165\n",
"2012-10-16 14:13:00 -0.692304 2012-10-16 13:58:00 0.833473\n",
"2012-10-16 14:14:00 -1.282011 2012-10-16 13:59:00 0.546800\n",
"2012-10-16 14:15:00 -0.817236 2012-10-16 14:03:00 0.577916\n",
"2012-10-16 14:16:00 -1.052183 2012-10-16 14:04:00 -0.622101\n",
"2012-10-16 14:17:00 0.526411 2012-10-16 14:06:00 -0.546126\n",
"2012-10-16 14:18:00 0.322879 2012-10-16 14:07:00 -0.368855\n",
"2012-10-16 14:19:00 -0.611969 2012-10-16 14:09:00 0.092263\n",
"2012-10-16 14:20:00 0.625695 2012-10-16 14:11:00 -1.856394\n",
"2012-10-16 14:23:00 -1.121760 2012-10-16 14:13:00 -0.127058\n",
"2012-10-16 14:24:00 -0.311206 2012-10-16 14:15:00 0.117108\n",
"2012-10-16 14:25:00 0.854759 2012-10-16 14:16:00 -0.935519\n",
"2012-10-16 14:27:00 0.348925 2012-10-16 14:17:00 -0.259812\n",
"2012-10-16 14:28:00 -0.420912 2012-10-16 14:18:00 0.376376\n",
"2012-10-16 14:29:00 0.616126 2012-10-16 14:21:00 -0.008942\n",
"2012-10-16 14:30:00 1.194879 2012-10-16 14:24:00 -0.387999\n",
"2012-10-16 14:31:00 -2.741125 2012-10-16 14:26:00 -0.718100\n",
"2012-10-16 14:32:00 -0.440264 2012-10-16 14:31:00 0.142147\n",
"2012-10-16 14:34:00 0.765335 2012-10-16 14:33:00 -0.832237\n",
"2012-10-16 14:35:00 -0.104913 2012-10-16 14:37:00 -0.568005\n",
"2012-10-16 14:37:00 -0.165425 2012-10-16 14:38:00 1.969672\n",
"2012-10-16 14:38:00 0.235925 2012-10-16 14:41:00 0.491619\n",
"2012-10-16 14:39:00 0.793851 2012-10-16 14:43:00 -0.228362\n",
"2012-10-16 14:42:00 0.908382 2012-10-16 14:44:00 -0.057909\n",
"2012-10-16 14:45:00 2.484144 2012-10-16 14:45:00 -0.529368\n",
"2012-10-16 14:48:00 -0.374788 2012-10-16 14:46:00 -1.567699\n",
"2012-10-16 14:50:00 1.132641 2012-10-16 14:49:00 1.529664\n",
"2012-10-16 14:54:00 1.723664 2012-10-16 14:50:00 1.671240\n",
"2012-10-16 14:57:00 -1.921218 2012-10-16 14:54:00 1.144198\n",
"2012-10-16 14:58:00 -0.270162 2012-10-16 14:58:00 -0.995039\n",
"2012-10-16 15:00:00 -0.574769 2012-10-16 15:01:00 -1.166899\n",
"2012-10-16 15:02:00 1.337077 2012-10-16 15:03:00 -1.681738\n",
"2012-10-16 15:03:00 -1.463414 2012-10-16 15:06:00 -1.136836\n",
"2012-10-16 15:05:00 -2.731812 2012-10-16 15:08:00 -1.855362\n",
"2012-10-16 15:07:00 0.619991 2012-10-16 15:09:00 0.574366\n",
"2012-10-16 15:08:00 0.565176 2012-10-16 15:12:00 0.912102\n",
"2012-10-16 15:10:00 -0.827944 2012-10-16 15:15:00 -0.562177\n",
"2012-10-16 15:13:00 -1.985925 2012-10-16 15:18:00 -0.206841\n",
"2012-10-16 15:16:00 -0.404277 2012-10-16 15:20:00 -1.404130\n",
"2012-10-16 15:21:00 1.767316 2012-10-16 15:22:00 -1.847907\n",
"2012-10-16 15:24:00 -0.135486 2012-10-16 15:23:00 -1.310254\n",
"2012-10-16 15:27:00 -2.335011 2012-10-16 15:25:00 0.892159\n",
"2012-10-16 15:28:00 0.207447 2012-10-16 15:26:00 0.524014\n",
"2012-10-16 15:29:00 -0.351660 2012-10-16 15:27:00 -0.529412\n",
"2012-10-16 15:30:00 0.966049 2012-10-16 15:28:00 -1.383748\n",
"2012-10-16 15:32:00 -2.378964 2012-10-16 15:31:00 1.134281\n",
"2012-10-16 15:34:00 -0.856666 2012-10-16 15:32:00 0.574123\n",
"2012-10-16 15:35:00 -1.055598 2012-10-16 15:33:00 0.687958\n",
"2012-10-16 15:37:00 -0.869997 2012-10-16 15:34:00 -0.797343\n",
"2012-10-16 15:38:00 1.722823 2012-10-16 15:37:00 1.165132\n",
"2012-10-16 15:39:00 -0.898471 2012-10-16 15:40:00 0.578093\n",
"2012-10-16 15:41:00 0.783874 2012-10-16 15:42:00 -0.362690\n",
"2012-10-16 15:43:00 -1.723552 2012-10-16 15:43:00 0.583491\n",
"2012-10-16 15:47:00 -0.477937 2012-10-16 15:44:00 -0.865897\n",
"2012-10-16 15:51:00 -0.174962 2012-10-16 15:48:00 2.424773\n",
"2012-10-16 15:52:00 -1.225221 2012-10-16 15:50:00 -0.146601\n",
"2012-10-16 15:55:00 1.083612 2012-10-16 15:54:00 0.570610\n",
"2012-10-16 15:56:00 0.116313 2012-10-16 15:55:00 -1.883469\n",
"2012-10-16 15:58:00 0.148215 2012-10-16 15:59:00 -1.942915\n",
"2012-10-16 15:59:00 -0.031988 2012-10-16 16:00:00 -0.826520\n",
"Length: 195 Length: 195 \n"
]
},
{
"output_type": "pyout",
"prompt_number": 147,
"text": [
"2012-10-16 09:32:00 NaN\n",
"2012-10-16 09:34:00 NaN\n",
"2012-10-16 09:35:00 -0.424035\n",
"2012-10-16 09:38:00 0.096810\n",
"2012-10-16 09:39:00 NaN\n",
"2012-10-16 09:40:00 -0.223288\n",
"2012-10-16 09:41:00 NaN\n",
"2012-10-16 09:43:00 NaN\n",
"2012-10-16 09:44:00 NaN\n",
"2012-10-16 09:47:00 0.566090\n",
"2012-10-16 09:48:00 0.318876\n",
"2012-10-16 09:50:00 NaN\n",
"2012-10-16 09:52:00 0.984125\n",
"2012-10-16 09:53:00 -0.363736\n",
"2012-10-16 09:54:00 NaN\n",
"2012-10-16 09:56:00 NaN\n",
"2012-10-16 09:57:00 0.143757\n",
"2012-10-16 09:59:00 NaN\n",
"2012-10-16 10:01:00 NaN\n",
"2012-10-16 10:03:00 NaN\n",
"2012-10-16 10:04:00 NaN\n",
"2012-10-16 10:05:00 0.460034\n",
"2012-10-16 10:06:00 -0.295201\n",
"2012-10-16 10:11:00 NaN\n",
"2012-10-16 10:13:00 NaN\n",
"2012-10-16 10:14:00 -2.032069\n",
"2012-10-16 10:15:00 -0.162541\n",
"2012-10-16 10:17:00 -0.926198\n",
"2012-10-16 10:25:00 NaN\n",
"2012-10-16 10:29:00 NaN\n",
"2012-10-16 10:30:00 -0.038478\n",
"2012-10-16 10:31:00 1.186224\n",
"2012-10-16 10:35:00 NaN\n",
"2012-10-16 10:36:00 NaN\n",
"2012-10-16 10:37:00 NaN\n",
"2012-10-16 10:38:00 -0.521280\n",
"2012-10-16 10:41:00 0.739980\n",
"2012-10-16 10:45:00 NaN\n",
"2012-10-16 10:46:00 NaN\n",
"2012-10-16 10:47:00 0.905588\n",
"2012-10-16 10:48:00 NaN\n",
"2012-10-16 10:50:00 NaN\n",
"2012-10-16 10:51:00 -0.004141\n",
"2012-10-16 10:52:00 NaN\n",
"2012-10-16 10:55:00 NaN\n",
"2012-10-16 10:56:00 NaN\n",
"2012-10-16 10:57:00 NaN\n",
"2012-10-16 10:58:00 NaN\n",
"2012-10-16 11:00:00 NaN\n",
"2012-10-16 11:02:00 NaN\n",
"2012-10-16 11:05:00 1.536359\n",
"2012-10-16 11:07:00 NaN\n",
"2012-10-16 11:11:00 -0.617283\n",
"2012-10-16 11:19:00 NaN\n",
"2012-10-16 11:20:00 NaN\n",
"2012-10-16 11:21:00 NaN\n",
"2012-10-16 11:22:00 NaN\n",
"2012-10-16 11:23:00 NaN\n",
"2012-10-16 11:25:00 -0.141152\n",
"2012-10-16 11:26:00 NaN\n",
"2012-10-16 11:28:00 -1.135601\n",
"2012-10-16 11:31:00 -0.748450\n",
"2012-10-16 11:32:00 1.071630\n",
"2012-10-16 11:34:00 0.683754\n",
"2012-10-16 11:35:00 NaN\n",
"2012-10-16 11:37:00 0.123272\n",
"2012-10-16 11:39:00 0.575960\n",
"2012-10-16 11:40:00 -0.375992\n",
"2012-10-16 11:42:00 -0.174095\n",
"2012-10-16 11:44:00 NaN\n",
"2012-10-16 11:45:00 NaN\n",
"2012-10-16 11:47:00 NaN\n",
"2012-10-16 11:49:00 1.470663\n",
"2012-10-16 11:55:00 0.044127\n",
"2012-10-16 12:04:00 NaN\n",
"2012-10-16 12:05:00 0.757033\n",
"2012-10-16 12:08:00 1.818434\n",
"2012-10-16 12:09:00 -1.027395\n",
"2012-10-16 12:10:00 NaN\n",
"2012-10-16 12:11:00 NaN\n",
"2012-10-16 12:14:00 NaN\n",
"2012-10-16 12:15:00 NaN\n",
"2012-10-16 12:20:00 1.876350\n",
"2012-10-16 12:22:00 NaN\n",
"2012-10-16 12:25:00 1.335344\n",
"2012-10-16 12:32:00 1.180517\n",
"2012-10-16 12:34:00 NaN\n",
"2012-10-16 12:35:00 0.517823\n",
"2012-10-16 12:39:00 NaN\n",
"2012-10-16 12:41:00 NaN\n",
"2012-10-16 12:43:00 0.333663\n",
"2012-10-16 12:47:00 NaN\n",
"2012-10-16 12:50:00 NaN\n",
"2012-10-16 12:52:00 NaN\n",
"2012-10-16 12:54:00 NaN\n",
"2012-10-16 12:55:00 0.082751\n",
"2012-10-16 12:56:00 NaN\n",
"2012-10-16 12:57:00 -0.395835\n",
"2012-10-16 12:58:00 1.370510\n",
"2012-10-16 12:59:00 -1.956925\n",
"2012-10-16 13:01:00 1.222593\n",
"2012-10-16 13:02:00 -0.445067\n",
"2012-10-16 13:03:00 -1.440613\n",
"2012-10-16 13:04:00 0.932419\n",
"2012-10-16 13:06:00 NaN\n",
"2012-10-16 13:08:00 0.744495\n",
"2012-10-16 13:11:00 0.983593\n",
"2012-10-16 13:12:00 NaN\n",
"2012-10-16 13:13:00 2.111926\n",
"2012-10-16 13:14:00 1.418948\n",
"2012-10-16 13:17:00 -0.009992\n",
"2012-10-16 13:18:00 NaN\n",
"2012-10-16 13:20:00 NaN\n",
"2012-10-16 13:21:00 1.285362\n",
"2012-10-16 13:23:00 -0.988116\n",
"2012-10-16 13:24:00 NaN\n",
"2012-10-16 13:25:00 -2.027632\n",
"2012-10-16 13:27:00 NaN\n",
"2012-10-16 13:28:00 -2.789475\n",
"2012-10-16 13:31:00 -0.027958\n",
"2012-10-16 13:32:00 NaN\n",
"2012-10-16 13:33:00 NaN\n",
"2012-10-16 13:34:00 NaN\n",
"2012-10-16 13:36:00 1.089322\n",
"2012-10-16 13:37:00 NaN\n",
"2012-10-16 13:40:00 -0.945711\n",
"2012-10-16 13:41:00 -0.563830\n",
"2012-10-16 13:42:00 NaN\n",
"2012-10-16 13:43:00 NaN\n",
"2012-10-16 13:46:00 0.504712\n",
"2012-10-16 13:50:00 NaN\n",
"2012-10-16 13:51:00 NaN\n",
"2012-10-16 13:54:00 NaN\n",
"2012-10-16 13:55:00 NaN\n",
"2012-10-16 13:56:00 -1.133351\n",
"2012-10-16 13:57:00 NaN\n",
"2012-10-16 13:58:00 NaN\n",
"2012-10-16 13:59:00 -0.745663\n",
"2012-10-16 14:03:00 0.898255\n",
"2012-10-16 14:04:00 1.186308\n",
"2012-10-16 14:06:00 NaN\n",
"2012-10-16 14:07:00 NaN\n",
"2012-10-16 14:09:00 NaN\n",
"2012-10-16 14:11:00 1.760259\n",
"2012-10-16 14:13:00 -0.692304\n",
"2012-10-16 14:15:00 -0.817236\n",
"2012-10-16 14:16:00 -1.052183\n",
"2012-10-16 14:17:00 0.526411\n",
"2012-10-16 14:18:00 0.322879\n",
"2012-10-16 14:21:00 NaN\n",
"2012-10-16 14:24:00 -0.311206\n",
"2012-10-16 14:26:00 NaN\n",
"2012-10-16 14:31:00 -2.741125\n",
"2012-10-16 14:33:00 NaN\n",
"2012-10-16 14:37:00 -0.165425\n",
"2012-10-16 14:38:00 0.235925\n",
"2012-10-16 14:41:00 NaN\n",
"2012-10-16 14:43:00 NaN\n",
"2012-10-16 14:44:00 NaN\n",
"2012-10-16 14:45:00 2.484144\n",
"2012-10-16 14:46:00 NaN\n",
"2012-10-16 14:49:00 NaN\n",
"2012-10-16 14:50:00 1.132641\n",
"2012-10-16 14:54:00 1.723664\n",
"2012-10-16 14:58:00 -0.270162\n",
"2012-10-16 15:01:00 NaN\n",
"2012-10-16 15:03:00 -1.463414\n",
"2012-10-16 15:06:00 NaN\n",
"2012-10-16 15:08:00 0.565176\n",
"2012-10-16 15:09:00 NaN\n",
"2012-10-16 15:12:00 NaN\n",
"2012-10-16 15:15:00 NaN\n",
"2012-10-16 15:18:00 NaN\n",
"2012-10-16 15:20:00 NaN\n",
"2012-10-16 15:22:00 NaN\n",
"2012-10-16 15:23:00 NaN\n",
"2012-10-16 15:25:00 NaN\n",
"2012-10-16 15:26:00 NaN\n",
"2012-10-16 15:27:00 -2.335011\n",
"2012-10-16 15:28:00 0.207447\n",
"2012-10-16 15:31:00 NaN\n",
"2012-10-16 15:32:00 -2.378964\n",
"2012-10-16 15:33:00 NaN\n",
"2012-10-16 15:34:00 -0.856666\n",
"2012-10-16 15:37:00 -0.869997\n",
"2012-10-16 15:40:00 NaN\n",
"2012-10-16 15:42:00 NaN\n",
"2012-10-16 15:43:00 -1.723552\n",
"2012-10-16 15:44:00 NaN\n",
"2012-10-16 15:48:00 NaN\n",
"2012-10-16 15:50:00 NaN\n",
"2012-10-16 15:54:00 NaN\n",
"2012-10-16 15:55:00 1.083612\n",
"2012-10-16 15:59:00 -0.031988\n",
"2012-10-16 16:00:00 NaN\n",
"Length: 195"
]
}
],
"prompt_number": 147
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment