├── .gitignore
├── 0. 10 minutes to Pandas.ipynb
├── 01. Dates & Times.ipynb
├── 02. Time Zone Handling.ipynb
├── 03. Reading and working with time-based data.ipynb
├── 04. Resampling.ipynb
├── 05. Moving Window Functions.ipynb
├── 07. Self Correlation.ipynb
├── 08. Trend&Seasonality.ipynb
├── 09a. AR + MA processes.ipynb
├── 09b. Forecasting.ipynb
├── 09c. Spectral Analysis.ipynb
├── 10. Clustering & Classification.ipynb
├── data
├── 50words_TEST.csv
├── AirPassengers.csv
├── Earthquakes.csv
├── ao_monthly.txt
└── yahoo_stock.csv
├── readtime.py
└── snippets
├── 6_acf_def.py
├── 6_acf_over_time.py
├── 6_ad_test_desc.py
├── 6_multi_vs_add.pu
├── 6_multi_vs_add.py
├── 6_pd.py
├── 6_var.py
├── 7_diff2.py
├── 7ma.py
├── ambig.py
├── changerep.py
├── confirm.py
├── custom_rolling.py
├── custom_rolling2.py
├── daterange.py
├── dtwdistance.py
├── euclidedistance.py
├── offset_aliases.py
├── prac1.py
├── prac2.py
├── prac3.py
├── prac4.py
├── prac5.py
├── prac6.py
├── prac7.py
├── prac8.py
├── readtime.py
├── resampling_end.py
├── shift_future.py
├── startend.py
├── try1.py
└── window_funcs_try.py
/.gitignore:
--------------------------------------------------------------------------------
1 | .ipynb_checkpoints/
2 |
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | env/
14 | build/
15 | develop-eggs/
16 | dist/
17 | downloads/
18 | eggs/
19 | .eggs/
20 | lib/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | .hypothesis/
50 |
51 | # Translations
52 | *.mo
53 | *.pot
54 |
55 | # Django stuff:
56 | *.log
57 | local_settings.py
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # dotenv
85 | .env
86 |
87 | # virtualenv
88 | .venv
89 | venv/
90 | ENV/
91 |
92 | # Spyder project settings
93 | .spyderproject
94 | .spyproject
95 |
96 | # Rope project settings
97 | .ropeproject
98 |
99 | # mkdocs documentation
100 | /site
101 |
102 | # mypy
103 | .mypy_cache/
--------------------------------------------------------------------------------
/0. 10 minutes to Pandas.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "%matplotlib inline \n",
12 | "import matplotlib.pylab\n",
13 | "import pandas as pd\n",
14 | "import numpy as np"
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "# Pandas data frames make data easy to see, references, and manipulate\n",
22 | "\n",
23 | "very much copied from\n",
24 | "http://pandas.pydata.org/pandas-docs/stable/10min.html"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "### You can create a data frame with a dictionary of lists"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": 2,
37 | "metadata": {
38 | "collapsed": false
39 | },
40 | "outputs": [
41 | {
42 | "data": {
43 | "text/html": [
44 | "
\n",
45 | "\n",
58 | "
\n",
59 | " \n",
60 | " \n",
61 | " | \n",
62 | " age | \n",
63 | " phone | \n",
64 | "
\n",
65 | " \n",
66 | " \n",
67 | " \n",
68 | " Melanie | \n",
69 | " 17 | \n",
70 | " 555-1212 | \n",
71 | "
\n",
72 | " \n",
73 | " Bob | \n",
74 | " 17 | \n",
75 | " 555-1234 | \n",
76 | "
\n",
77 | " \n",
78 | " Vidhya | \n",
79 | " 18 | \n",
80 | " 555-1111 | \n",
81 | "
\n",
82 | " \n",
83 | " Ming | \n",
84 | " 18 | \n",
85 | " 555-2222 | \n",
86 | "
\n",
87 | " \n",
88 | "
\n",
89 | "
"
90 | ],
91 | "text/plain": [
92 | "\n",
93 | " age phone\n",
94 | "Melanie 17 555-1212\n",
95 | "Bob 17 555-1234\n",
96 | "Vidhya 18 555-1111\n",
97 | "Ming 18 555-2222"
98 | ]
99 | },
100 | "metadata": {},
101 | "output_type": "display_data"
102 | }
103 | ],
104 | "source": [
105 | "students = pd.DataFrame({'phone': ['555-1212', '555-1234', '555-1111', '555-2222'], 'age':[17, 17, 18, 18]}, index = ['Melanie', 'Bob', 'Vidhya', 'Ming'])\n",
106 | "students"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": 3,
112 | "metadata": {
113 | "collapsed": false
114 | },
115 | "outputs": [
116 | {
117 | "data": {
118 | "text/plain": [
119 | "Index(['Melanie', 'Bob', 'Vidhya', 'Ming'], dtype='object')"
120 | ]
121 | },
122 | "execution_count": 3,
123 | "metadata": {},
124 | "output_type": "execute_result"
125 | }
126 | ],
127 | "source": [
128 | "students.index"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "### You can also create a data frame with a numpy array and some column names"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 4,
141 | "metadata": {
142 | "collapsed": false
143 | },
144 | "outputs": [
145 | {
146 | "data": {
147 | "text/html": [
148 | "\n",
149 | "\n",
162 | "
\n",
163 | " \n",
164 | " \n",
165 | " | \n",
166 | " A | \n",
167 | " B | \n",
168 | " C | \n",
169 | " D | \n",
170 | "
\n",
171 | " \n",
172 | " \n",
173 | " \n",
174 | " Jenny | \n",
175 | " -0.293866 | \n",
176 | " -0.011147 | \n",
177 | " -0.811072 | \n",
178 | " 0.777268 | \n",
179 | "
\n",
180 | " \n",
181 | " Frank | \n",
182 | " -0.583124 | \n",
183 | " 0.829852 | \n",
184 | " -1.161750 | \n",
185 | " 0.070804 | \n",
186 | "
\n",
187 | " \n",
188 | " Wenfei | \n",
189 | " 0.100019 | \n",
190 | " -0.838110 | \n",
191 | " 0.820974 | \n",
192 | " 0.016191 | \n",
193 | "
\n",
194 | " \n",
195 | " Arun | \n",
196 | " 1.700588 | \n",
197 | " -0.368254 | \n",
198 | " 0.938544 | \n",
199 | " -0.084392 | \n",
200 | "
\n",
201 | " \n",
202 | " Mary | \n",
203 | " -1.201694 | \n",
204 | " 1.401805 | \n",
205 | " -0.375543 | \n",
206 | " 0.682025 | \n",
207 | "
\n",
208 | " \n",
209 | " Ivan | \n",
210 | " 0.887998 | \n",
211 | " 0.700713 | \n",
212 | " -1.589795 | \n",
213 | " -0.143907 | \n",
214 | "
\n",
215 | " \n",
216 | "
\n",
217 | "
"
218 | ],
219 | "text/plain": [
220 | "\n",
221 | " A B C D\n",
222 | "Jenny -0.293866 -0.011147 -0.811072 0.777268\n",
223 | "Frank -0.583124 0.829852 -1.161750 0.070804\n",
224 | "Wenfei 0.100019 -0.838110 0.820974 0.016191\n",
225 | "Arun 1.700588 -0.368254 0.938544 -0.084392\n",
226 | "Mary -1.201694 1.401805 -0.375543 0.682025\n",
227 | "Ivan 0.887998 0.700713 -1.589795 -0.143907"
228 | ]
229 | },
230 | "metadata": {},
231 | "output_type": "display_data"
232 | }
233 | ],
234 | "source": [
235 | "df = pd.DataFrame(np.random.randn(6,4), index=['Jenny', 'Frank', 'Wenfei', 'Arun', 'Mary', 'Ivan'], columns=list('ABCD'))\n",
236 | "df"
237 | ]
238 | },
239 | {
240 | "cell_type": "markdown",
241 | "metadata": {},
242 | "source": [
243 | "### There are also Series, which gets you all the functionality of a data frame when you have a 1-dimensional set of data with an index"
244 | ]
245 | },
246 | {
247 | "cell_type": "code",
248 | "execution_count": 5,
249 | "metadata": {
250 | "collapsed": false
251 | },
252 | "outputs": [],
253 | "source": [
254 | "s = pd.Series([1,3,5,np.nan,6,8])"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": 6,
260 | "metadata": {
261 | "collapsed": false
262 | },
263 | "outputs": [
264 | {
265 | "data": {
266 | "text/plain": [
267 | "\n",
268 | "a 1.0\n",
269 | "b 3.0\n",
270 | "c 5.0\n",
271 | "d NaN\n",
272 | "e 6.0\n",
273 | "f 8.0\n",
274 | "dtype: float64"
275 | ]
276 | },
277 | "metadata": {},
278 | "output_type": "display_data"
279 | }
280 | ],
281 | "source": [
282 | "s.index = ['a', 'b', 'c', 'd', 'e', 'f']\n",
283 | "s"
284 | ]
285 | },
286 | {
287 | "cell_type": "code",
288 | "execution_count": 7,
289 | "metadata": {
290 | "collapsed": false
291 | },
292 | "outputs": [
293 | {
294 | "data": {
295 | "text/plain": [
296 | "\n",
297 | "a False\n",
298 | "b False\n",
299 | "c False\n",
300 | "d True\n",
301 | "e False\n",
302 | "f False\n",
303 | "dtype: bool"
304 | ]
305 | },
306 | "metadata": {},
307 | "output_type": "display_data"
308 | }
309 | ],
310 | "source": [
311 | "s.isnull()"
312 | ]
313 | },
314 | {
315 | "cell_type": "markdown",
316 | "metadata": {},
317 | "source": [
318 | "### Dataframes and series play nice with plotting"
319 | ]
320 | },
321 | {
322 | "cell_type": "code",
323 | "execution_count": 8,
324 | "metadata": {
325 | "collapsed": false
326 | },
327 | "outputs": [
328 | {
329 | "data": {
330 | "text/plain": [
331 | ""
332 | ]
333 | },
334 | "execution_count": 8,
335 | "metadata": {},
336 | "output_type": "execute_result"
337 | },
338 | {
339 | "data": {
340 | "image/png": "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\nB/wZRGQZjj0AAAAASUVORK5CYII=\n",
341 | "text/plain": [
342 | ""
343 | ]
344 | },
345 | "metadata": {},
346 | "output_type": "display_data"
347 | }
348 | ],
349 | "source": [
350 | "s.plot()"
351 | ]
352 | },
353 | {
354 | "cell_type": "code",
355 | "execution_count": 9,
356 | "metadata": {
357 | "collapsed": false
358 | },
359 | "outputs": [
360 | {
361 | "data": {
362 | "text/plain": [
363 | ""
364 | ]
365 | },
366 | "execution_count": 9,
367 | "metadata": {},
368 | "output_type": "execute_result"
369 | },
370 | {
371 | "data": {
372 | "image/png": "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\nL0XdpRegAAAAAElFTkSuQmCC\n",
373 | "text/plain": [
374 | ""
375 | ]
376 | },
377 | "metadata": {},
378 | "output_type": "display_data"
379 | }
380 | ],
381 | "source": [
382 | "df.plot()"
383 | ]
384 | },
385 | {
386 | "cell_type": "markdown",
387 | "metadata": {},
388 | "source": [
389 | "### Once you have a data frame, it's easy to see portions of your data that match what you want (same goes for series)"
390 | ]
391 | },
392 | {
393 | "cell_type": "code",
394 | "execution_count": 10,
395 | "metadata": {
396 | "collapsed": false
397 | },
398 | "outputs": [
399 | {
400 | "data": {
401 | "text/plain": [
402 | "\n",
403 | "d NaN\n",
404 | "e 6.0\n",
405 | "f 8.0\n",
406 | "dtype: float64"
407 | ]
408 | },
409 | "metadata": {},
410 | "output_type": "display_data"
411 | }
412 | ],
413 | "source": [
414 | "s[s.index > 'c']"
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": 11,
420 | "metadata": {
421 | "collapsed": false
422 | },
423 | "outputs": [
424 | {
425 | "data": {
426 | "text/plain": [
427 | "\n",
428 | "a 1.0\n",
429 | "b 3.0\n",
430 | "c 5.0\n",
431 | "e 6.0\n",
432 | "f 8.0\n",
433 | "dtype: float64"
434 | ]
435 | },
436 | "metadata": {},
437 | "output_type": "display_data"
438 | }
439 | ],
440 | "source": [
441 | "s[s.isnull() == False]"
442 | ]
443 | },
444 | {
445 | "cell_type": "code",
446 | "execution_count": 12,
447 | "metadata": {
448 | "collapsed": false
449 | },
450 | "outputs": [
451 | {
452 | "data": {
453 | "text/plain": [
454 | "\n",
455 | "Melanie 17\n",
456 | "Bob 17\n",
457 | "Vidhya 18\n",
458 | "Ming 18\n",
459 | "Name: age, dtype: int64"
460 | ]
461 | },
462 | "metadata": {},
463 | "output_type": "display_data"
464 | }
465 | ],
466 | "source": [
467 | "students['age']"
468 | ]
469 | },
470 | {
471 | "cell_type": "code",
472 | "execution_count": 13,
473 | "metadata": {
474 | "collapsed": false
475 | },
476 | "outputs": [
477 | {
478 | "data": {
479 | "text/plain": [
480 | "\n",
481 | "Melanie 17\n",
482 | "Bob 17\n",
483 | "Vidhya 18\n",
484 | "Ming 18\n",
485 | "Name: age, dtype: int64"
486 | ]
487 | },
488 | "metadata": {},
489 | "output_type": "display_data"
490 | }
491 | ],
492 | "source": [
493 | "students.age"
494 | ]
495 | },
496 | {
497 | "cell_type": "code",
498 | "execution_count": 14,
499 | "metadata": {
500 | "collapsed": false
501 | },
502 | "outputs": [
503 | {
504 | "data": {
505 | "text/plain": [
506 | "\n",
507 | "age 17\n",
508 | "phone 555-1212\n",
509 | "Name: Melanie, dtype: object"
510 | ]
511 | },
512 | "metadata": {},
513 | "output_type": "display_data"
514 | }
515 | ],
516 | "source": [
517 | "# 'selection by label'\n",
518 | "students.loc['Melanie']"
519 | ]
520 | },
521 | {
522 | "cell_type": "code",
523 | "execution_count": 15,
524 | "metadata": {
525 | "collapsed": false
526 | },
527 | "outputs": [
528 | {
529 | "data": {
530 | "text/plain": [
531 | "\n",
532 | "age 17\n",
533 | "grades NaN\n",
534 | "Name: Melanie, dtype: object"
535 | ]
536 | },
537 | "metadata": {},
538 | "output_type": "display_data"
539 | }
540 | ],
541 | "source": [
542 | "students.loc['Melanie', ['age', 'grades']]"
543 | ]
544 | },
545 | {
546 | "cell_type": "code",
547 | "execution_count": 16,
548 | "metadata": {
549 | "collapsed": false
550 | },
551 | "outputs": [
552 | {
553 | "data": {
554 | "text/plain": [
555 | "\n",
556 | "age 17\n",
557 | "phone 555-1234\n",
558 | "Name: Bob, dtype: object"
559 | ]
560 | },
561 | "metadata": {},
562 | "output_type": "display_data"
563 | }
564 | ],
565 | "source": [
566 | "# select by position\n",
567 | "students.iloc[1, :]"
568 | ]
569 | },
570 | {
571 | "cell_type": "code",
572 | "execution_count": 17,
573 | "metadata": {
574 | "collapsed": false
575 | },
576 | "outputs": [
577 | {
578 | "data": {
579 | "text/html": [
580 | "\n",
581 | "\n",
594 | "
\n",
595 | " \n",
596 | " \n",
597 | " | \n",
598 | " age | \n",
599 | " phone | \n",
600 | "
\n",
601 | " \n",
602 | " \n",
603 | " \n",
604 | " Vidhya | \n",
605 | " 18 | \n",
606 | " 555-1111 | \n",
607 | "
\n",
608 | " \n",
609 | " Ming | \n",
610 | " 18 | \n",
611 | " 555-2222 | \n",
612 | "
\n",
613 | " \n",
614 | "
\n",
615 | "
"
616 | ],
617 | "text/plain": [
618 | "\n",
619 | " age phone\n",
620 | "Vidhya 18 555-1111\n",
621 | "Ming 18 555-2222"
622 | ]
623 | },
624 | "metadata": {},
625 | "output_type": "display_data"
626 | }
627 | ],
628 | "source": [
629 | "students[students['age'] > 17]"
630 | ]
631 | },
632 | {
633 | "cell_type": "markdown",
634 | "metadata": {},
635 | "source": [
636 | "### It's also easy to summarize your data"
637 | ]
638 | },
639 | {
640 | "cell_type": "code",
641 | "execution_count": 19,
642 | "metadata": {
643 | "collapsed": false
644 | },
645 | "outputs": [
646 | {
647 | "data": {
648 | "text/plain": [
649 | "17.5"
650 | ]
651 | },
652 | "execution_count": 19,
653 | "metadata": {},
654 | "output_type": "execute_result"
655 | }
656 | ],
657 | "source": [
658 | "students.age.mean()"
659 | ]
660 | },
661 | {
662 | "cell_type": "code",
663 | "execution_count": 20,
664 | "metadata": {
665 | "collapsed": false
666 | },
667 | "outputs": [
668 | {
669 | "data": {
670 | "text/plain": [
671 | "18"
672 | ]
673 | },
674 | "execution_count": 20,
675 | "metadata": {},
676 | "output_type": "execute_result"
677 | }
678 | ],
679 | "source": [
680 | "students.age.max()"
681 | ]
682 | },
683 | {
684 | "cell_type": "code",
685 | "execution_count": 21,
686 | "metadata": {
687 | "collapsed": false
688 | },
689 | "outputs": [
690 | {
691 | "data": {
692 | "text/plain": [
693 | "17"
694 | ]
695 | },
696 | "execution_count": 21,
697 | "metadata": {},
698 | "output_type": "execute_result"
699 | }
700 | ],
701 | "source": [
702 | "students.age.min()"
703 | ]
704 | },
705 | {
706 | "cell_type": "markdown",
707 | "metadata": {},
708 | "source": [
709 | "### You can add information to an existing data frame"
710 | ]
711 | },
712 | {
713 | "cell_type": "code",
714 | "execution_count": 22,
715 | "metadata": {
716 | "collapsed": false
717 | },
718 | "outputs": [],
719 | "source": [
720 | "students['grade'] = [100, 97, 80, 85]"
721 | ]
722 | },
723 | {
724 | "cell_type": "code",
725 | "execution_count": 23,
726 | "metadata": {
727 | "collapsed": false
728 | },
729 | "outputs": [
730 | {
731 | "data": {
732 | "text/html": [
733 | "\n",
734 | "\n",
747 | "
\n",
748 | " \n",
749 | " \n",
750 | " | \n",
751 | " age | \n",
752 | " phone | \n",
753 | " grade | \n",
754 | "
\n",
755 | " \n",
756 | " \n",
757 | " \n",
758 | " Melanie | \n",
759 | " 17 | \n",
760 | " 555-1212 | \n",
761 | " 100 | \n",
762 | "
\n",
763 | " \n",
764 | "
\n",
765 | "
"
766 | ],
767 | "text/plain": [
768 | "\n",
769 | " age phone grade\n",
770 | "Melanie 17 555-1212 100"
771 | ]
772 | },
773 | "metadata": {},
774 | "output_type": "display_data"
775 | }
776 | ],
777 | "source": [
778 | "students[students['grade'] == students['grade'].max()]"
779 | ]
780 | },
781 | {
782 | "cell_type": "markdown",
783 | "metadata": {},
784 | "source": [
785 | "### You can also easily aggregate information"
786 | ]
787 | },
788 | {
789 | "cell_type": "code",
790 | "execution_count": 24,
791 | "metadata": {
792 | "collapsed": false
793 | },
794 | "outputs": [
795 | {
796 | "data": {
797 | "text/plain": [
798 | "\n",
799 | "age\n",
800 | "17 98.5\n",
801 | "18 82.5\n",
802 | "Name: grade, dtype: float64"
803 | ]
804 | },
805 | "metadata": {},
806 | "output_type": "display_data"
807 | }
808 | ],
809 | "source": [
810 | "students.groupby('age').grade.mean()"
811 | ]
812 | },
813 | {
814 | "cell_type": "markdown",
815 | "metadata": {},
816 | "source": [
817 | "### You can even create categories to aggregate with on-the-fly"
818 | ]
819 | },
820 | {
821 | "cell_type": "code",
822 | "execution_count": 25,
823 | "metadata": {
824 | "collapsed": false
825 | },
826 | "outputs": [
827 | {
828 | "data": {
829 | "text/plain": [
830 | "\n",
831 | "1 18.0\n",
832 | "2 17.5\n",
833 | "3 17.0\n",
834 | "Name: age, dtype: float64"
835 | ]
836 | },
837 | "metadata": {},
838 | "output_type": "display_data"
839 | }
840 | ],
841 | "source": [
842 | "bins = np.linspace(70, 100, 3)\n",
843 | "bins\n",
844 | "students.groupby(np.digitize(students.grade, bins)).age.mean()"
845 | ]
846 | },
847 | {
848 | "cell_type": "markdown",
849 | "metadata": {},
850 | "source": [
851 | "### Finally applying functions is also quite straight-forward"
852 | ]
853 | },
854 | {
855 | "cell_type": "code",
856 | "execution_count": 26,
857 | "metadata": {
858 | "collapsed": true
859 | },
860 | "outputs": [],
861 | "source": [
862 | "# First let's see what a lambda function looks like / does\n",
863 | "f = lambda x: x + 1"
864 | ]
865 | },
866 | {
867 | "cell_type": "code",
868 | "execution_count": 27,
869 | "metadata": {
870 | "collapsed": false
871 | },
872 | "outputs": [
873 | {
874 | "data": {
875 | "text/plain": [
876 | "5"
877 | ]
878 | },
879 | "execution_count": 27,
880 | "metadata": {},
881 | "output_type": "execute_result"
882 | }
883 | ],
884 | "source": [
885 | "f(4)"
886 | ]
887 | },
888 | {
889 | "cell_type": "code",
890 | "execution_count": 28,
891 | "metadata": {
892 | "collapsed": false
893 | },
894 | "outputs": [
895 | {
896 | "data": {
897 | "text/plain": [
898 | "\n",
899 | "Melanie 18\n",
900 | "Bob 18\n",
901 | "Vidhya 19\n",
902 | "Ming 19\n",
903 | "Name: age, dtype: int64"
904 | ]
905 | },
906 | "metadata": {},
907 | "output_type": "display_data"
908 | }
909 | ],
910 | "source": [
911 | "students.age.apply(lambda age: age + 1)"
912 | ]
913 | },
914 | {
915 | "cell_type": "markdown",
916 | "metadata": {},
917 | "source": [
918 | "### Let's take a look at some built methods we might want to apply"
919 | ]
920 | },
921 | {
922 | "cell_type": "code",
923 | "execution_count": null,
924 | "metadata": {
925 | "collapsed": false
926 | },
927 | "outputs": [],
928 | "source": [
929 | "students.age.mean()"
930 | ]
931 | },
932 | {
933 | "cell_type": "code",
934 | "execution_count": null,
935 | "metadata": {
936 | "collapsed": false
937 | },
938 | "outputs": [],
939 | "source": [
940 | "students.age.count()"
941 | ]
942 | },
943 | {
944 | "cell_type": "code",
945 | "execution_count": null,
946 | "metadata": {
947 | "collapsed": false
948 | },
949 | "outputs": [],
950 | "source": [
951 | "students.corr()"
952 | ]
953 | },
954 | {
955 | "cell_type": "code",
956 | "execution_count": null,
957 | "metadata": {
958 | "collapsed": false
959 | },
960 | "outputs": [],
961 | "source": [
962 | "students.cummax()"
963 | ]
964 | }
965 | ],
966 | "metadata": {
967 | "anaconda-cloud": {},
968 | "kernelspec": {
969 | "display_name": "Python [Root]",
970 | "language": "python",
971 | "name": "Python [Root]"
972 | },
973 | "language_info": {
974 | "codemirror_mode": {
975 | "name": "ipython",
976 | "version": 3
977 | },
978 | "file_extension": ".py",
979 | "mimetype": "text/x-python",
980 | "name": "python",
981 | "nbconvert_exporter": "python",
982 | "pygments_lexer": "ipython3",
983 | "version": "3.5.2"
984 | },
985 | "widgets": {
986 | "state": {},
987 | "version": "1.1.1"
988 | }
989 | },
990 | "nbformat": 4,
991 | "nbformat_minor": 0
992 | }
993 |
--------------------------------------------------------------------------------
/01. Dates & Times.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import pandas as pd\n",
12 | "import numpy as np"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {},
18 | "source": [
19 | "# Generate series of times"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": null,
25 | "metadata": {
26 | "collapsed": false
27 | },
28 | "outputs": [],
29 | "source": [
30 | "# specify with start date & number of periods\n",
31 | "rng = pd.date_range('2016 Jul 15 10:15', periods = 10, freq = 'M')\n",
32 | "rng"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {
38 | "collapsed": true
39 | },
40 | "source": [
41 | "### let's explore some of the other options for date_range\n",
42 | "http://pandas.pydata.org/pandas-docs/stable/generated/pandas.date_range.html\n",
43 | "\n",
44 | "In particular, let's take a look at 'normalize' and 'end'"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {
51 | "collapsed": false
52 | },
53 | "outputs": [],
54 | "source": [
55 | "rng = pd.date_range('2016 Jul 15', periods = 10, freq = 'M')\n",
56 | "rng"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "# Timestamps"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {
70 | "collapsed": false
71 | },
72 | "outputs": [],
73 | "source": [
74 | "# add increasing detail\n",
75 | "pd.Timestamp('2016-07-10')"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {
82 | "collapsed": false
83 | },
84 | "outputs": [],
85 | "source": [
86 | "pd.Timestamp('2016-07-10 10:15:15')"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "### How much detail can you add?"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {
100 | "collapsed": false
101 | },
102 | "outputs": [],
103 | "source": [
104 | "pd.Timestamp('2016-07-10 10:15:15.05675757')"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "### Which of these formats DON'T work?\n",
112 | "'2016 Jul 1', '7/1/2016', '1/7/2016', 'July 1, 2016', '2016-07-01'"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {
119 | "collapsed": true
120 | },
121 | "outputs": [],
122 | "source": []
123 | },
124 | {
125 | "cell_type": "markdown",
126 | "metadata": {},
127 | "source": [
128 | "### What are some properties of time stamps? \n",
129 | "Hint: http://pandas.pydata.org/pandas-docs/stable/timeseries.html#time-date-components"
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": null,
135 | "metadata": {
136 | "collapsed": true
137 | },
138 | "outputs": [],
139 | "source": [
140 | "t = pd.Timestamp('2016-07-10 10:15:15')"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {
147 | "collapsed": false
148 | },
149 | "outputs": [],
150 | "source": [
151 | "t.quarter"
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": null,
157 | "metadata": {
158 | "collapsed": false
159 | },
160 | "outputs": [],
161 | "source": [
162 | "t = pd.Timestamp('2016-07-10 8 pm')\n",
163 | "t"
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {},
169 | "source": [
170 | "### How are time stamps lacking?"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {
177 | "collapsed": true
178 | },
179 | "outputs": [],
180 | "source": []
181 | },
182 | {
183 | "cell_type": "markdown",
184 | "metadata": {},
185 | "source": [
186 | "# Time offsets"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "metadata": {
193 | "collapsed": false
194 | },
195 | "outputs": [],
196 | "source": [
197 | "pd.Timedelta('1 day 1us')"
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {
204 | "collapsed": false
205 | },
206 | "outputs": [],
207 | "source": [
208 | "pd.Timestamp('2016-07-01 8:00') + pd.Timedelta('1.5 hours')"
209 | ]
210 | },
211 | {
212 | "cell_type": "code",
213 | "execution_count": null,
214 | "metadata": {
215 | "collapsed": false
216 | },
217 | "outputs": [],
218 | "source": [
219 | "pd.Timedelta('15ns') #bug? what kind of bug?"
220 | ]
221 | },
222 | {
223 | "cell_type": "code",
224 | "execution_count": null,
225 | "metadata": {
226 | "collapsed": false
227 | },
228 | "outputs": [],
229 | "source": [
230 | "rng + pd.Timedelta('1day')"
231 | ]
232 | },
233 | {
234 | "cell_type": "markdown",
235 | "metadata": {},
236 | "source": [
237 | "# Time spans"
238 | ]
239 | },
240 | {
241 | "cell_type": "code",
242 | "execution_count": null,
243 | "metadata": {
244 | "collapsed": false
245 | },
246 | "outputs": [],
247 | "source": [
248 | "p = pd.Period('7/2016')\n",
249 | "t = pd.Timestamp('7/21/2016')\n",
250 | "p.start_time < t and p.end_time > t"
251 | ]
252 | },
253 | {
254 | "cell_type": "code",
255 | "execution_count": null,
256 | "metadata": {
257 | "collapsed": false
258 | },
259 | "outputs": [],
260 | "source": [
261 | "rng = pd.period_range('2016-01-01 12:15', freq = 'H', periods = 10)\n",
262 | "rng"
263 | ]
264 | },
265 | {
266 | "cell_type": "code",
267 | "execution_count": null,
268 | "metadata": {
269 | "collapsed": false
270 | },
271 | "outputs": [],
272 | "source": [
273 | "rng = pd.period_range('2016-01-01 12:15', freq = '60T', periods = 10)\n",
274 | "rng"
275 | ]
276 | },
277 | {
278 | "cell_type": "code",
279 | "execution_count": null,
280 | "metadata": {
281 | "collapsed": false
282 | },
283 | "outputs": [],
284 | "source": [
285 | "rng = pd.period_range('2016-01-01 12:15', freq = '1H', periods = 10)\n",
286 | "rng"
287 | ]
288 | },
289 | {
290 | "cell_type": "markdown",
291 | "metadata": {},
292 | "source": [
293 | "### How can you determine whether a timestamp falls within a given period?"
294 | ]
295 | },
296 | {
297 | "cell_type": "code",
298 | "execution_count": null,
299 | "metadata": {
300 | "collapsed": false
301 | },
302 | "outputs": [],
303 | "source": [
304 | "%load snippets/startend.py"
305 | ]
306 | },
307 | {
308 | "cell_type": "markdown",
309 | "metadata": {},
310 | "source": [
311 | "### Try out some other functionality with different offset-aliases. Anything interesting?\n",
312 | "\n",
313 | "http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases"
314 | ]
315 | },
316 | {
317 | "cell_type": "code",
318 | "execution_count": null,
319 | "metadata": {
320 | "collapsed": false
321 | },
322 | "outputs": [],
323 | "source": [
324 | "# %load snippets/offset_aliases.py"
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "metadata": {},
330 | "source": [
331 | "### How can you make a pandas Time Series with these aliases?"
332 | ]
333 | },
334 | {
335 | "cell_type": "code",
336 | "execution_count": null,
337 | "metadata": {
338 | "collapsed": false
339 | },
340 | "outputs": [],
341 | "source": [
342 | "num_periods = 40\n",
343 | "ts_pd = pd.Series(range(num_periods), pd.period_range('2016-07-01 11:15', freq = '60T', periods = num_periods))"
344 | ]
345 | },
346 | {
347 | "cell_type": "code",
348 | "execution_count": null,
349 | "metadata": {
350 | "collapsed": false
351 | },
352 | "outputs": [],
353 | "source": [
354 | "ts_pd['2016-7-1 11':'2016-7-1 13']"
355 | ]
356 | },
357 | {
358 | "cell_type": "markdown",
359 | "metadata": {},
360 | "source": [
361 | "### How can we index a time series with a date_range?"
362 | ]
363 | },
364 | {
365 | "cell_type": "code",
366 | "execution_count": null,
367 | "metadata": {
368 | "collapsed": true
369 | },
370 | "outputs": [],
371 | "source": [
372 | "num_periods = 40\n",
373 | "ts_dt = pd.Series(range(num_periods), pd.date_range('2016-07-01 11:15', freq = '60T', periods = num_periods))"
374 | ]
375 | },
376 | {
377 | "cell_type": "markdown",
378 | "metadata": {},
379 | "source": [
380 | "### What are the use cases for a series with a DateTimeIndex vs a PeriodIndex? Where will we see a difference?"
381 | ]
382 | },
383 | {
384 | "cell_type": "code",
385 | "execution_count": null,
386 | "metadata": {
387 | "collapsed": false
388 | },
389 | "outputs": [],
390 | "source": [
391 | "ts_dt['2016-7-1 11']"
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": null,
397 | "metadata": {
398 | "collapsed": false
399 | },
400 | "outputs": [],
401 | "source": [
402 | "ts_pd['2016-7-1 11':'2016-7-1 13']"
403 | ]
404 | },
405 | {
406 | "cell_type": "markdown",
407 | "metadata": {},
408 | "source": [
409 | "### How can we convert between a DateTimeIndex and a PeriodIndex?"
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": null,
415 | "metadata": {
416 | "collapsed": false
417 | },
418 | "outputs": [],
419 | "source": [
420 | "ts_dt.to_period()\n",
421 | "ts_pd.to_timestamp()"
422 | ]
423 | },
424 | {
425 | "cell_type": "markdown",
426 | "metadata": {},
427 | "source": [
428 | "# Try\n",
429 | "\n",
430 | "(1) How can you create a pd.Timestamp with a European style formatted date string? hint: dayfirst flag\n",
431 | "\n",
432 | "(2) How can you generate string representation in a desired format from a pd.Timestamp? "
433 | ]
434 | },
435 | {
436 | "cell_type": "code",
437 | "execution_count": null,
438 | "metadata": {
439 | "collapsed": false
440 | },
441 | "outputs": [],
442 | "source": [
443 | "# %load snippets/try1.py"
444 | ]
445 | }
446 | ],
447 | "metadata": {
448 | "kernelspec": {
449 | "display_name": "Python 3",
450 | "language": "python",
451 | "name": "python3"
452 | },
453 | "language_info": {
454 | "codemirror_mode": {
455 | "name": "ipython",
456 | "version": 3
457 | },
458 | "file_extension": ".py",
459 | "mimetype": "text/x-python",
460 | "name": "python",
461 | "nbconvert_exporter": "python",
462 | "pygments_lexer": "ipython3",
463 | "version": "3.5.3"
464 | },
465 | "widgets": {
466 | "state": {},
467 | "version": "1.1.1"
468 | }
469 | },
470 | "nbformat": 4,
471 | "nbformat_minor": 0
472 | }
473 |
--------------------------------------------------------------------------------
/02. Time Zone Handling.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import numpy as np \n",
12 | "import pandas as pd"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {},
18 | "source": [
19 | "# pandas Time zone information"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": null,
25 | "metadata": {
26 | "collapsed": true
27 | },
28 | "outputs": [],
29 | "source": [
30 | "rng = pd.date_range('3/6/2016 00:00', periods = 15, freq = 'd')\n",
31 | "rng.tz"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {
38 | "collapsed": false
39 | },
40 | "outputs": [],
41 | "source": [
42 | "rng = pd.date_range('3/6/2016 00:00', periods = 15, freq = 'd', tz = 'Europe/London')\n",
43 | "rng.tz"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "### Getting lists of time zones"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {
57 | "collapsed": false
58 | },
59 | "outputs": [],
60 | "source": [
61 | "from pytz import common_timezones, all_timezones\n",
62 | "print(len(common_timezones))"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "metadata": {
69 | "collapsed": false
70 | },
71 | "outputs": [],
72 | "source": [
73 | "print(len(all_timezones))"
74 | ]
75 | },
76 | {
77 | "cell_type": "markdown",
78 | "metadata": {},
79 | "source": [
80 | "### What are some time zones not considered 'common'?"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "collapsed": false
88 | },
89 | "outputs": [],
90 | "source": [
91 | "set(all_timezones).difference(set(common_timezones))"
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "### Localizing a timestamp"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "metadata": {
105 | "collapsed": false
106 | },
107 | "outputs": [],
108 | "source": [
109 | "t_naive = pd.Timestamp('2016-05-05 08:15')\n",
110 | "t_naive"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "metadata": {
117 | "collapsed": false
118 | },
119 | "outputs": [],
120 | "source": [
121 | "t = t_naive.tz_localize(tz = 'US/Central')\n",
122 | "t"
123 | ]
124 | },
125 | {
126 | "cell_type": "code",
127 | "execution_count": null,
128 | "metadata": {
129 | "collapsed": false
130 | },
131 | "outputs": [],
132 | "source": [
133 | "t_naive"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": null,
139 | "metadata": {
140 | "collapsed": false
141 | },
142 | "outputs": [],
143 | "source": [
144 | "t.tz_convert('Asia/Tokyo')"
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {
151 | "collapsed": false
152 | },
153 | "outputs": [],
154 | "source": [
155 | "t"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "### What is the difference between tz_convert and tz_localize?\n",
163 | "\n",
164 | "hint: try to run tz_convert on a naive time stamp"
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "### Fun with daylight savings"
172 | ]
173 | },
174 | {
175 | "cell_type": "code",
176 | "execution_count": null,
177 | "metadata": {
178 | "collapsed": false
179 | },
180 | "outputs": [],
181 | "source": [
182 | "# You'll get weirdness with timezones based on daylight savings:\n",
183 | "rng = pd.date_range('2016-03-10', periods = 10, tz = 'US/Eastern')\n",
184 | "ts = pd.Series(range(10), index = rng)\n",
185 | "# What do you notice below?\n",
186 | "ts"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "### Ambiguous times"
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": null,
199 | "metadata": {
200 | "collapsed": true
201 | },
202 | "outputs": [],
203 | "source": [
204 | "# For the same reason you can run into 'ambiguous' dates\n",
205 | "rng_hourly = pd.DatetimeIndex(['11/06/2011 00:00', '11/06/2011 01:00','11/06/2011 01:00', '11/06/2011 02:00','11/06/2011 03:00'])"
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": null,
211 | "metadata": {
212 | "collapsed": false
213 | },
214 | "outputs": [],
215 | "source": [
216 | "# What happens if we localize?\n",
217 | "rng_hourly.tz_localize('US/Central')"
218 | ]
219 | },
220 | {
221 | "cell_type": "markdown",
222 | "metadata": {},
223 | "source": [
224 | "### How do we deal with this ambiguous time error?\n",
225 | "hint: http://pandas.pydata.org/pandas-docs/stable/timeseries.html#ambiguous-times-when-localizing"
226 | ]
227 | },
228 | {
229 | "cell_type": "code",
230 | "execution_count": null,
231 | "metadata": {
232 | "collapsed": false
233 | },
234 | "outputs": [],
235 | "source": [
236 | "# %load snippets/ambig.py\n",
237 | "rng_hourly.tz_localize('US/Central', ambiguous = 'infer')"
238 | ]
239 | },
240 | {
241 | "cell_type": "markdown",
242 | "metadata": {},
243 | "source": [
244 | "### How can we check whether the inference did what we wanted?"
245 | ]
246 | },
247 | {
248 | "cell_type": "code",
249 | "execution_count": null,
250 | "metadata": {
251 | "collapsed": false
252 | },
253 | "outputs": [],
254 | "source": [
255 | "# %load snippets/confirm.py\n",
256 | "rng_hourly.tz_localize('US/Central', ambiguous = 'infer').tz_convert('utc')"
257 | ]
258 | },
259 | {
260 | "cell_type": "markdown",
261 | "metadata": {},
262 | "source": [
263 | "### Pandas goes to amazing length to try to figure things out for you"
264 | ]
265 | },
266 | {
267 | "cell_type": "code",
268 | "execution_count": null,
269 | "metadata": {
270 | "collapsed": false
271 | },
272 | "outputs": [],
273 | "source": [
274 | "# What's going on here?\n",
275 | "pd.Timestamp('2016-03-13 02:00', tz = 'US/Eastern')"
276 | ]
277 | },
278 | {
279 | "cell_type": "code",
280 | "execution_count": null,
281 | "metadata": {
282 | "collapsed": true
283 | },
284 | "outputs": [],
285 | "source": []
286 | }
287 | ],
288 | "metadata": {
289 | "kernelspec": {
290 | "display_name": "Python 3",
291 | "language": "python",
292 | "name": "python3"
293 | },
294 | "language_info": {
295 | "codemirror_mode": {
296 | "name": "ipython",
297 | "version": 3
298 | },
299 | "file_extension": ".py",
300 | "mimetype": "text/x-python",
301 | "name": "python",
302 | "nbconvert_exporter": "python",
303 | "pygments_lexer": "ipython3",
304 | "version": "3.5.3"
305 | },
306 | "widgets": {
307 | "state": {},
308 | "version": "1.1.1"
309 | }
310 | },
311 | "nbformat": 4,
312 | "nbformat_minor": 0
313 | }
314 |
--------------------------------------------------------------------------------
/03. Reading and working with time-based data.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "%matplotlib inline \n",
12 | "import matplotlib.pylab\n",
13 | "import pandas as pd\n",
14 | "import numpy as np"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {
21 | "collapsed": false
22 | },
23 | "outputs": [],
24 | "source": [
25 | "with open('data/ao_monthly.txt') as f:\n",
26 | " for x in range(5):\n",
27 | " print(next(f))"
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": null,
33 | "metadata": {
34 | "collapsed": false
35 | },
36 | "outputs": [],
37 | "source": [
38 | "data = pd.read_fwf('data/ao_monthly.txt', header = None)"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {
45 | "collapsed": false
46 | },
47 | "outputs": [],
48 | "source": [
49 | "# Not so great\n",
50 | "data.head()"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "### Look at the options for read_fwf...what looks relevant?"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {
64 | "collapsed": false
65 | },
66 | "outputs": [],
67 | "source": [
68 | "# %load snippets/readtime.py\n",
69 | "data = pd.read_fwf('data/ao_monthly.txt', header = None, index_col = 0, parse_dates = [[0, 1]], infer_datetime_format = True)"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {
76 | "collapsed": false
77 | },
78 | "outputs": [],
79 | "source": [
80 | "data.head()"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "collapsed": false
88 | },
89 | "outputs": [],
90 | "source": [
91 | "data.index"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {
98 | "collapsed": false
99 | },
100 | "outputs": [],
101 | "source": [
102 | "data.index.names = ['Month']\n",
103 | "data.columns = ['Value']\n",
104 | "data.head()"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "### What is the empirical range of dates?"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": null,
117 | "metadata": {
118 | "collapsed": false
119 | },
120 | "outputs": [],
121 | "source": [
122 | "# %load snippets/daterange.py\n",
123 | "print(min(data.index))\n",
124 | "print(max(data.index))"
125 | ]
126 | },
127 | {
128 | "cell_type": "markdown",
129 | "metadata": {},
130 | "source": [
131 | "### How can we convert to complementary representation?"
132 | ]
133 | },
134 | {
135 | "cell_type": "code",
136 | "execution_count": null,
137 | "metadata": {
138 | "collapsed": false
139 | },
140 | "outputs": [],
141 | "source": [
142 | "# %load snippets/changerep.py\n",
143 | "data.to_period()"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "### More about reading in data\n",
151 | "\n",
152 | "When reading in dates with a pd.read function, you have several time-related parameters you can adjust: \n",
153 | "parse_dates, infer_datetime_format, date_parser\n",
154 | "\n",
155 | "Experiment with these using %timeit to see if there are performance differences\n",
156 | "\n",
157 | "Hint:\n",
158 | "infer_datetime_format = True, no date parser provided.\n",
159 | "What other combos can you come up with?"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "metadata": {
166 | "collapsed": false
167 | },
168 | "outputs": [],
169 | "source": [
170 | "import timeit\n",
171 | "# First, let's see how to use a date_parser:\n",
172 | "dateparse = lambda x, y: pd.datetime.strptime('%s-%s'%(x,y), '%Y-%m')\n",
173 | "\n",
174 | "%timeit data = pd.read_fwf('data/ao_monthly.txt', header = None, index_col = 0, parse_dates = [[0, 1]], date_parser = dateparse)"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": null,
180 | "metadata": {
181 | "collapsed": false
182 | },
183 | "outputs": [],
184 | "source": [
185 | "data.head()"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": null,
191 | "metadata": {
192 | "collapsed": false
193 | },
194 | "outputs": [],
195 | "source": [
196 | "%timeit data = pd.read_fwf('data/ao_monthly.txt', header = None, index_col = 0, parse_dates = [[0, 1]])"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "collapsed": false
204 | },
205 | "outputs": [],
206 | "source": [
207 | "%timeit data = pd.read_fwf('data/ao_monthly.txt', header = None, index_col = 0, parse_dates = [[0, 1]], infer_datetime_format = True)"
208 | ]
209 | },
210 | {
211 | "cell_type": "markdown",
212 | "metadata": {},
213 | "source": [
214 | "### You can also extract datetimes from existing Data Frame columns"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "metadata": {
221 | "collapsed": false
222 | },
223 | "outputs": [],
224 | "source": [
225 | "# new in pandas 0.18\n",
226 | "df = pd.DataFrame({'year':[2015, 2016], 'month':[2,3], 'day':[4,5], 'hour':[12, 13]})\n",
227 | "df"
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "metadata": {
234 | "collapsed": false
235 | },
236 | "outputs": [],
237 | "source": [
238 | "pd.to_datetime(df)"
239 | ]
240 | },
241 | {
242 | "cell_type": "code",
243 | "execution_count": null,
244 | "metadata": {
245 | "collapsed": false
246 | },
247 | "outputs": [],
248 | "source": [
249 | "# BUT\n",
250 | "df['value'] = 17\n",
251 | "pd.to_datetime(df)"
252 | ]
253 | },
254 | {
255 | "cell_type": "markdown",
256 | "metadata": {},
257 | "source": [
258 | "### Truncating"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": null,
264 | "metadata": {
265 | "collapsed": false
266 | },
267 | "outputs": [],
268 | "source": [
269 | "ts = pd.Series(range(10), index = pd.date_range('7/31/15', freq = 'M', periods = 10))\n",
270 | "ts"
271 | ]
272 | },
273 | {
274 | "cell_type": "code",
275 | "execution_count": null,
276 | "metadata": {
277 | "collapsed": false
278 | },
279 | "outputs": [],
280 | "source": [
281 | "# truncating preserves frequency\n",
282 | "ts.truncate(before = '10/31/2015', after = '12/31/2015')"
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "execution_count": null,
288 | "metadata": {
289 | "collapsed": false,
290 | "scrolled": true
291 | },
292 | "outputs": [],
293 | "source": [
294 | "# You can truncate in a way that does not preserve frequency\n",
295 | "ts[[1, 6, 7]].index"
296 | ]
297 | },
298 | {
299 | "cell_type": "code",
300 | "execution_count": null,
301 | "metadata": {
302 | "collapsed": false
303 | },
304 | "outputs": [],
305 | "source": [
306 | "# But Pandas will try to preserve frequency automatically whenever possible/logical\n",
307 | "ts[0:10:2]"
308 | ]
309 | }
310 | ],
311 | "metadata": {
312 | "kernelspec": {
313 | "display_name": "Python 3",
314 | "language": "python",
315 | "name": "python3"
316 | },
317 | "language_info": {
318 | "codemirror_mode": {
319 | "name": "ipython",
320 | "version": 3
321 | },
322 | "file_extension": ".py",
323 | "mimetype": "text/x-python",
324 | "name": "python",
325 | "nbconvert_exporter": "python",
326 | "pygments_lexer": "ipython3",
327 | "version": "3.5.3"
328 | },
329 | "widgets": {
330 | "state": {},
331 | "version": "1.1.1"
332 | }
333 | },
334 | "nbformat": 4,
335 | "nbformat_minor": 0
336 | }
337 |
--------------------------------------------------------------------------------
/04. Resampling.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import pandas as pd\n",
12 | "import numpy as np"
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": null,
18 | "metadata": {
19 | "collapsed": false
20 | },
21 | "outputs": [],
22 | "source": [
23 | "rng = pd.date_range('1/1/2011', periods = 72, freq = 'H')\n",
24 | "ts = pd.Series(list(range(len(rng))), index = rng)"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {
31 | "collapsed": false
32 | },
33 | "outputs": [],
34 | "source": [
35 | "ts.head()"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {
42 | "collapsed": true
43 | },
44 | "outputs": [],
45 | "source": [
46 | "converted = ts.asfreq('45Min', method = 'ffill')\n",
47 | "# try 'ffill', 'bfill', None"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": null,
53 | "metadata": {
54 | "collapsed": false
55 | },
56 | "outputs": [],
57 | "source": [
58 | "converted.head()"
59 | ]
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "metadata": {},
64 | "source": [
65 | "### What does the above code do to the size and content of your data frame?"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": null,
71 | "metadata": {
72 | "collapsed": false
73 | },
74 | "outputs": [],
75 | "source": [
76 | "converted[1:10]"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": false
84 | },
85 | "outputs": [],
86 | "source": [
87 | "ts[1:10]"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": null,
93 | "metadata": {
94 | "collapsed": false
95 | },
96 | "outputs": [],
97 | "source": [
98 | "converted.shape"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "metadata": {
105 | "collapsed": false
106 | },
107 | "outputs": [],
108 | "source": [
109 | "ts.shape"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "### Take a look at the specs for .asfreq(). What are your options for filling in missing data?"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": null,
122 | "metadata": {
123 | "collapsed": true
124 | },
125 | "outputs": [],
126 | "source": [
127 | "ts.asfreq??"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {},
133 | "source": [
134 | "### How can you go to less frequent rather than more frequent?"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": null,
140 | "metadata": {
141 | "collapsed": true
142 | },
143 | "outputs": [],
144 | "source": [
145 | "converted = ts.asfreq('3H')"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": false
153 | },
154 | "outputs": [],
155 | "source": [
156 | "converted[1:10]"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {
163 | "collapsed": false
164 | },
165 | "outputs": [],
166 | "source": [
167 | "ts[1:10]"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": null,
173 | "metadata": {
174 | "collapsed": false
175 | },
176 | "outputs": [],
177 | "source": [
178 | "# Let's try the more flexible .resample()\n",
179 | "ts.resample('2H', label = 'right').mean()[:10]"
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {
186 | "collapsed": true
187 | },
188 | "outputs": [],
189 | "source": [
190 | "ts.resample??"
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": null,
196 | "metadata": {
197 | "collapsed": false
198 | },
199 | "outputs": [],
200 | "source": [
201 | "# What's particularly useful is that we can use reample to event out irregular time series\n",
202 | "irreg_ts = ts[list(np.random.choice(a = list(range(len(ts))), size = 10, replace = False))]"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {
209 | "collapsed": false
210 | },
211 | "outputs": [],
212 | "source": [
213 | "irreg_ts"
214 | ]
215 | },
216 | {
217 | "cell_type": "code",
218 | "execution_count": null,
219 | "metadata": {
220 | "collapsed": false
221 | },
222 | "outputs": [],
223 | "source": [
224 | "irreg_ts.asfreq('D')"
225 | ]
226 | },
227 | {
228 | "cell_type": "markdown",
229 | "metadata": {},
230 | "source": [
231 | "### Why didn't that work?"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {
238 | "collapsed": false
239 | },
240 | "outputs": [],
241 | "source": [
242 | "irreg_ts = irreg_ts.sort_index()\n",
243 | "irreg_ts"
244 | ]
245 | },
246 | {
247 | "cell_type": "code",
248 | "execution_count": null,
249 | "metadata": {
250 | "collapsed": false
251 | },
252 | "outputs": [],
253 | "source": [
254 | "irreg_ts.asfreq('D', method = 'bfill')"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": null,
260 | "metadata": {
261 | "collapsed": false
262 | },
263 | "outputs": [],
264 | "source": [
265 | "irreg_ts.resample('D').mean()"
266 | ]
267 | },
268 | {
269 | "cell_type": "markdown",
270 | "metadata": {},
271 | "source": [
272 | "# Try\n",
273 | "\n",
274 | "(1) What if you want to go to a higher frequency, but you don't want to back fill or forward fill? Why might you want to do that?\n",
275 | "\n",
276 | "(2) What is the difference between .resample() and .asfreq()?\n",
277 | "\n",
278 | "(3) How can I forward-fill only a few days? (hint: .fillna())\n",
279 | "\n",
280 | "(4) What are some helpful functions to use with a Resampler object?"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": null,
286 | "metadata": {
287 | "collapsed": false
288 | },
289 | "outputs": [],
290 | "source": [
291 | "# %load snippets/resampling_end.py"
292 | ]
293 | },
294 | {
295 | "cell_type": "code",
296 | "execution_count": null,
297 | "metadata": {
298 | "collapsed": true
299 | },
300 | "outputs": [],
301 | "source": []
302 | }
303 | ],
304 | "metadata": {
305 | "kernelspec": {
306 | "display_name": "Python 3",
307 | "language": "python",
308 | "name": "python3"
309 | },
310 | "language_info": {
311 | "codemirror_mode": {
312 | "name": "ipython",
313 | "version": 3
314 | },
315 | "file_extension": ".py",
316 | "mimetype": "text/x-python",
317 | "name": "python",
318 | "nbconvert_exporter": "python",
319 | "pygments_lexer": "ipython3",
320 | "version": "3.5.3"
321 | },
322 | "widgets": {
323 | "state": {},
324 | "version": "1.1.1"
325 | }
326 | },
327 | "nbformat": 4,
328 | "nbformat_minor": 0
329 | }
330 |
--------------------------------------------------------------------------------
/05. Moving Window Functions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "%matplotlib inline\n",
12 | "import matplotlib.pylab\n",
13 | "\n",
14 | "%pylab inline\n",
15 | "pylab.rcParams['figure.figsize'] = (10, 6)\n",
16 | "\n",
17 | "import numpy as np\n",
18 | "import pandas as pd"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "# The special thing about time series is that data points relate to one another...they are not independent\n",
26 | "So we can to compare them and relate them. One way to do this is to look at how they change. For example, we can 'difference' a time series"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "metadata": {
33 | "collapsed": false
34 | },
35 | "outputs": [],
36 | "source": [
37 | "ts = pd.Series(np.random.randn(20) + 10, pd.date_range('7/1/16', freq = 'D', periods = 20))\n",
38 | "ts_lagged = ts.shift()"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {
45 | "collapsed": false
46 | },
47 | "outputs": [],
48 | "source": [
49 | "ts.head()"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": null,
55 | "metadata": {
56 | "collapsed": false
57 | },
58 | "outputs": [],
59 | "source": [
60 | "ts_lagged.head()"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": null,
66 | "metadata": {
67 | "collapsed": false
68 | },
69 | "outputs": [],
70 | "source": [
71 | "ts.diff()"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {
78 | "collapsed": false
79 | },
80 | "outputs": [],
81 | "source": [
82 | "plt.plot(ts, color = 'blue')\n",
83 | "plt.plot(ts_lagged, color = 'red')\n",
84 | "plt.plot(ts - ts_lagged, color = 'green')"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "### But the need to difference is quite common, so Pandas does it for you"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {
98 | "collapsed": false
99 | },
100 | "outputs": [],
101 | "source": [
102 | "plt.plot(ts.diff(), color = 'black')"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "### Query: how can I shift my time series 'into the future' instead of into the past?"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": null,
115 | "metadata": {
116 | "collapsed": false
117 | },
118 | "outputs": [],
119 | "source": [
120 | "# %load snippets/shift_future.py"
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {},
126 | "source": [
127 | "# Window functions give you moving aggregate measures of a time series"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": true
135 | },
136 | "outputs": [],
137 | "source": [
138 | "# Window functions are like aggregation/summary functions\n",
139 | "# You can use them in conjunction with .resample()"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": null,
145 | "metadata": {
146 | "collapsed": true
147 | },
148 | "outputs": [],
149 | "source": [
150 | "df = pd.DataFrame(np.random.randn(600, 3), index = pd.date_range('5/1/2016', freq = 'D', periods = 600), columns = ['A', 'B', 'C'])"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "metadata": {
157 | "collapsed": false
158 | },
159 | "outputs": [],
160 | "source": [
161 | "r = df.rolling(window = 20)\n",
162 | "r"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {
169 | "collapsed": false
170 | },
171 | "outputs": [],
172 | "source": [
173 | "df['A'].plot(color = 'gray')\n",
174 | "r.mean()['A'].plot(color = 'red')"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": null,
180 | "metadata": {
181 | "collapsed": false
182 | },
183 | "outputs": [],
184 | "source": [
185 | "df['A'].plot(color = 'gray')\n",
186 | "r.min()['A'].plot(color = 'red')"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "### Try out some of these options with .rolling()\n",
194 | "\n",
195 | "r.agg, r.apply, r.count, r.max, r.median, r.name, r.quantile, r.kurt, \n",
196 | "r.aggregate, r.std, r.skew, r.sum, r.var"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "collapsed": false
204 | },
205 | "outputs": [],
206 | "source": [
207 | "df['A'].plot(color = 'gray')\n",
208 | "r.quantile(.30)['A'].plot(color = 'red')"
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "### What about a custom function?"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": null,
221 | "metadata": {
222 | "collapsed": false
223 | },
224 | "outputs": [],
225 | "source": [
226 | "# %load snippets/custom_rolling.py"
227 | ]
228 | },
229 | {
230 | "cell_type": "code",
231 | "execution_count": null,
232 | "metadata": {
233 | "collapsed": false
234 | },
235 | "outputs": [],
236 | "source": [
237 | "# %load snippets/custom_rolling2.py"
238 | ]
239 | },
240 | {
241 | "cell_type": "markdown",
242 | "metadata": {},
243 | "source": [
244 | "## Expanding windows"
245 | ]
246 | },
247 | {
248 | "cell_type": "code",
249 | "execution_count": null,
250 | "metadata": {
251 | "collapsed": false
252 | },
253 | "outputs": [],
254 | "source": [
255 | "df.expanding(min_periods = 1).mean()[1:5]"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": null,
261 | "metadata": {
262 | "collapsed": false
263 | },
264 | "outputs": [],
265 | "source": [
266 | "df.expanding(min_periods = 1).median().plot()"
267 | ]
268 | },
269 | {
270 | "cell_type": "markdown",
271 | "metadata": {},
272 | "source": [
273 | "# Try"
274 | ]
275 | },
276 | {
277 | "cell_type": "markdown",
278 | "metadata": {},
279 | "source": [
280 | "(1) How can you perform an exponentially weight moving average rather than a window function? (hint: look for ewma + pandas docs)\n",
281 | "\n",
282 | "(2) When would you use an expanding window vs. a rolling window?\n",
283 | "\n",
284 | "(3) Write a custom function to repace .quantile(.5) function for a moving average\n",
285 | "\n",
286 | "(4) How would you compute more than one aggregation function on a moving window function at the same time? "
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {
293 | "collapsed": false
294 | },
295 | "outputs": [],
296 | "source": [
297 | "# %load snippets/window_funcs_try.py"
298 | ]
299 | },
300 | {
301 | "cell_type": "code",
302 | "execution_count": null,
303 | "metadata": {
304 | "collapsed": true
305 | },
306 | "outputs": [],
307 | "source": []
308 | }
309 | ],
310 | "metadata": {
311 | "anaconda-cloud": {},
312 | "kernelspec": {
313 | "display_name": "Python [Root]",
314 | "language": "python",
315 | "name": "Python [Root]"
316 | },
317 | "language_info": {
318 | "codemirror_mode": {
319 | "name": "ipython",
320 | "version": 3
321 | },
322 | "file_extension": ".py",
323 | "mimetype": "text/x-python",
324 | "name": "python",
325 | "nbconvert_exporter": "python",
326 | "pygments_lexer": "ipython3",
327 | "version": "3.5.2"
328 | },
329 | "widgets": {
330 | "state": {},
331 | "version": "1.1.1"
332 | }
333 | },
334 | "nbformat": 4,
335 | "nbformat_minor": 0
336 | }
337 |
--------------------------------------------------------------------------------
/09a. AR + MA processes.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "%matplotlib inline\n",
12 | "import matplotlib.pylab as plt\n",
13 | "\n",
14 | "import pandas as pd\n",
15 | "import numpy as np\n",
16 | "\n",
17 | "from statsmodels.tsa.stattools import acf, pacf"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "### First let's figure out how to generate an AR proces"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {
31 | "collapsed": false
32 | },
33 | "outputs": [],
34 | "source": [
35 | "def ar1(phi = .9, n = 1000, init = 0):\n",
36 | " time_series = [init]\n",
37 | " error = np.random.randn(n)\n",
38 | " for period in range(n):\n",
39 | " time_series.append(error[period] + phi*time_series[-1])\n",
40 | " return pd.Series(time_series[1:], index = range(n))\n",
41 | " \n",
42 | "def ar2(phi1 = .9, phi2 = -.8, n = 1000, init = 0):\n",
43 | " time_series = [init, init]\n",
44 | " error = np.random.randn(n)\n",
45 | " for period in range(2,n):\n",
46 | " time_series.append(error[period] + phi1*time_series[-1] + phi2*time_series[-2])\n",
47 | " return pd.Series(time_series[1:], index = range(1,n))\n",
48 | " "
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {
55 | "collapsed": false
56 | },
57 | "outputs": [],
58 | "source": [
59 | "# try out different values of phi >=1 as compared to < 1\n",
60 | "# sometimes you need to make a large n to see lack of stationarity\n",
61 | "a1 = ar1(phi = 1.1, n = 40)\n",
62 | "a1.plot()"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "metadata": {
69 | "collapsed": false
70 | },
71 | "outputs": [],
72 | "source": [
73 | "# try out different values of phi >=1 as compared to < 1\n",
74 | "# sometimes you need to make a large n to see lack of stationarity\n",
75 | "a2 = ar2(n = 50, phi2 = 1.7)\n",
76 | "a2.plot()"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "### Now let's generate an MA process"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": null,
89 | "metadata": {
90 | "collapsed": false
91 | },
92 | "outputs": [],
93 | "source": [
94 | "# %load snippets/7ma.py"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {
101 | "collapsed": false
102 | },
103 | "outputs": [],
104 | "source": [
105 | "m1 = ma1(theta = -1000)\n",
106 | "m1.plot()"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {},
112 | "source": [
113 | "### Let's look at ACF + PACF for each kind of process"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {
120 | "collapsed": false
121 | },
122 | "outputs": [],
123 | "source": [
124 | "a1 = ar1(phi = .5, n = 1000)\n",
125 | "a1_acf = acf(a1, nlags = 20)\n",
126 | "plt.plot(a1_acf)\n",
127 | "plt.axhline(y=0,linestyle='--', color = 'black')\n",
128 | "plt.axhline(y=-1.96/np.sqrt(len(a1)),linestyle='--', color = 'red')\n",
129 | "plt.axhline(y=1.96/np.sqrt(len(a1)),linestyle='--', color = 'red')"
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": null,
135 | "metadata": {
136 | "collapsed": false
137 | },
138 | "outputs": [],
139 | "source": [
140 | "a1 = ar1(phi = .5, n = 1000)\n",
141 | "a1_pacf = pacf(a1, nlags = 20)\n",
142 | "plt.plot(a1_pacf)\n",
143 | "plt.axhline(y=0,linestyle='--', color = 'black')\n",
144 | "plt.axhline(y=-1.96/np.sqrt(len(a1)),linestyle='--', color = 'red')\n",
145 | "plt.axhline(y=1.96/np.sqrt(len(a1)),linestyle='--', color = 'red')"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": false
153 | },
154 | "outputs": [],
155 | "source": [
156 | "m1 = ma1(n = 1000, theta = .9)\n",
157 | "m1_acf = acf(m1, nlags = 20)\n",
158 | "plt.plot(m1_acf)\n",
159 | "plt.axhline(y=0,linestyle='--', color = 'black')\n",
160 | "plt.axhline(y=-1.96/np.sqrt(len(m1)),linestyle='--', color = 'red')\n",
161 | "plt.axhline(y=1.96/np.sqrt(len(m1)),linestyle='--', color = 'red')"
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": null,
167 | "metadata": {
168 | "collapsed": false
169 | },
170 | "outputs": [],
171 | "source": [
172 | "m1 = ma1(n = 1000, theta = .9)\n",
173 | "m1_pacf = pacf(m1, nlags = 20)\n",
174 | "plt.plot(m1_pacf)\n",
175 | "plt.axhline(y=0,linestyle='--', color = 'black')\n",
176 | "plt.axhline(y=-1.96/np.sqrt(len(m1)),linestyle='--', color = 'red')\n",
177 | "plt.axhline(y=1.96/np.sqrt(len(m1)),linestyle='--', color = 'red')"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {
184 | "collapsed": true
185 | },
186 | "outputs": [],
187 | "source": []
188 | }
189 | ],
190 | "metadata": {
191 | "anaconda-cloud": {},
192 | "kernelspec": {
193 | "display_name": "Python [Root]",
194 | "language": "python",
195 | "name": "Python [Root]"
196 | },
197 | "language_info": {
198 | "codemirror_mode": {
199 | "name": "ipython",
200 | "version": 3
201 | },
202 | "file_extension": ".py",
203 | "mimetype": "text/x-python",
204 | "name": "python",
205 | "nbconvert_exporter": "python",
206 | "pygments_lexer": "ipython3",
207 | "version": "3.5.2"
208 | },
209 | "widgets": {
210 | "state": {},
211 | "version": "1.1.1"
212 | }
213 | },
214 | "nbformat": 4,
215 | "nbformat_minor": 0
216 | }
217 |
--------------------------------------------------------------------------------
/09b. Forecasting.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import pandas as pd\n",
12 | "import numpy as np\n",
13 | "import matplotlib.pylab as plt\n",
14 | "%matplotlib inline\n",
15 | "from matplotlib.pylab import rcParams\n",
16 | "rcParams['figure.figsize'] = 15, 6"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# Let's do a quick and dirty detrend"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {
30 | "collapsed": false
31 | },
32 | "outputs": [],
33 | "source": [
34 | "air_passengers = pd.read_csv(\"./data/AirPassengers.csv\", header = 0, parse_dates = [0], names = ['Month', 'Passengers'], index_col = 0)"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {
41 | "collapsed": false
42 | },
43 | "outputs": [],
44 | "source": [
45 | "log_air_passengers = np.log(air_passengers.Passengers)"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {
52 | "collapsed": false
53 | },
54 | "outputs": [],
55 | "source": [
56 | "log_air_passengers_diff = log_air_passengers - log_air_passengers.shift()"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": null,
62 | "metadata": {
63 | "collapsed": false
64 | },
65 | "outputs": [],
66 | "source": [
67 | "plt.plot(log_air_passengers_diff)"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "### By the way, how would I difference again?"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": null,
80 | "metadata": {
81 | "collapsed": false
82 | },
83 | "outputs": [],
84 | "source": [
85 | "# %load snippets/7_diff2.py\n",
86 | "\n"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "### What information are you losing when you difference? What about when you difference twice?"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {
100 | "collapsed": true
101 | },
102 | "outputs": [],
103 | "source": [
104 | "# think physics!"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "metadata": {
111 | "collapsed": false
112 | },
113 | "outputs": [],
114 | "source": [
115 | "log_air_passengers_diff.dropna(inplace=True)"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": null,
121 | "metadata": {
122 | "collapsed": false
123 | },
124 | "outputs": [],
125 | "source": [
126 | "# try out nc, ct, ctt\n",
127 | "# http://www.statsmodels.org/0.6.1/generated/statsmodels.tsa.stattools.adfuller.html\n",
128 | "from statsmodels.tsa.stattools import adfuller\n",
129 | "useful_values_raw = adfuller(log_air_passengers_diff, autolag = 'AIC', regression = 'c')[:5]\n",
130 | "useful_values = [v for v in useful_values_raw[:4]]\n",
131 | "useful_values.extend([useful_values_raw[4]['1%'], useful_values_raw[4]['5%'], useful_values_raw[4]['10%']])\n",
132 | "pd.DataFrame({ 'Value':useful_values, 'Label':['Test Statistic','p-value','#Lags Used','Number of Observations Used', 'Critical value for 1%', 'Critical value for 5%', 'Critical value for 10%']})"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {
139 | "collapsed": true
140 | },
141 | "outputs": [],
142 | "source": [
143 | "# Let's talk about the ARIMA model\n",
144 | "# Auto-Regressive Integrated Moving Average\n",
145 | "# In this case we're talking about a series with dependence among values (more natural)"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": true
153 | },
154 | "outputs": [],
155 | "source": [
156 | "# Nothing but a linear regression with a few times\n",
157 | "# 1. The number of Auto-Regressive Terms (p)\n",
158 | "# 2. The number of differences taken (d)\n",
159 | "# 3. The number of Moving Average Terms (q)"
160 | ]
161 | },
162 | {
163 | "cell_type": "markdown",
164 | "metadata": {},
165 | "source": [
166 | "# Let's do it"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {
173 | "collapsed": false
174 | },
175 | "outputs": [],
176 | "source": [
177 | "# We don't pull these out of thin air, but rather draw them from the data\n",
178 | "from statsmodels.tsa.stattools import acf, pacf\n",
179 | "\n",
180 | "lag_acf = acf(log_air_passengers_diff.values, nlags = 20)\n",
181 | "lag_pacf = pacf(log_air_passengers_diff.values, nlags = 20)"
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "metadata": {
188 | "collapsed": false
189 | },
190 | "outputs": [],
191 | "source": [
192 | "plt.subplot(121) \n",
193 | "plt.bar(left = range(len(lag_acf)), height = lag_acf)\n",
194 | "plt.axhline(y=0,linestyle='--')\n",
195 | "plt.axhline(y=-1.96/np.sqrt(len(log_air_passengers_diff)),linestyle='--')\n",
196 | "plt.axhline(y=1.96/np.sqrt(len(log_air_passengers_diff)),linestyle='--')"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "collapsed": true
204 | },
205 | "outputs": [],
206 | "source": [
207 | "# look at where the plot crosses the upper confidence interval for the first time\n",
208 | "# for ACF this is 1 and gives us the p value"
209 | ]
210 | },
211 | {
212 | "cell_type": "code",
213 | "execution_count": null,
214 | "metadata": {
215 | "collapsed": false
216 | },
217 | "outputs": [],
218 | "source": [
219 | "plt.subplot(121) \n",
220 | "plt.bar(left = range(len(lag_pacf)), height = lag_pacf)\n",
221 | "plt.axhline(y=0,linestyle='--')\n",
222 | "plt.axhline(y=-1.96/np.sqrt(len(log_air_passengers_diff)),linestyle='--')\n",
223 | "plt.axhline(y=1.96/np.sqrt(len(log_air_passengers_diff)),linestyle='--')"
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": null,
229 | "metadata": {
230 | "collapsed": true
231 | },
232 | "outputs": [],
233 | "source": [
234 | "# look at where the plot crosses the upper confidence interval for the first time\n",
235 | "# for PACF this is 2 and gives us the p value"
236 | ]
237 | },
238 | {
239 | "cell_type": "code",
240 | "execution_count": null,
241 | "metadata": {
242 | "collapsed": true
243 | },
244 | "outputs": [],
245 | "source": [
246 | "from statsmodels.tsa.arima_model import ARIMA"
247 | ]
248 | },
249 | {
250 | "cell_type": "code",
251 | "execution_count": null,
252 | "metadata": {
253 | "collapsed": false
254 | },
255 | "outputs": [],
256 | "source": [
257 | "# AR model\n",
258 | "# try different values of p\n",
259 | "model = ARIMA(log_air_passengers, order=(2, 1, 0)) \n",
260 | "results_AR = model.fit(disp=-1) \n",
261 | "plt.plot(log_air_passengers_diff)\n",
262 | "plt.plot(results_AR.fittedvalues, color='red')\n",
263 | "plt.title('RSS: %.4f'% sum((results_AR.fittedvalues-log_air_passengers_diff)**2))"
264 | ]
265 | },
266 | {
267 | "cell_type": "code",
268 | "execution_count": null,
269 | "metadata": {
270 | "collapsed": false
271 | },
272 | "outputs": [],
273 | "source": [
274 | "# try different values of q\n",
275 | "# MA model\n",
276 | "model = ARIMA(log_air_passengers, order=(0, 1, 1)) \n",
277 | "results_MA = model.fit(disp=-1) \n",
278 | "plt.plot(log_air_passengers_diff)\n",
279 | "plt.plot(results_MA.fittedvalues, color='red')\n",
280 | "plt.title('RSS: %.4f'% sum((results_MA.fittedvalues-log_air_passengers_diff)**2))"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": null,
286 | "metadata": {
287 | "collapsed": false
288 | },
289 | "outputs": [],
290 | "source": [
291 | "# ARIMA model\n",
292 | "# try p = 1 or 2\n",
293 | "model = ARIMA(log_air_passengers, order=(1, 1, 1)) \n",
294 | "results_ARIMA = model.fit(disp=-1) \n",
295 | "plt.plot(log_air_passengers_diff)\n",
296 | "plt.plot(results_ARIMA.fittedvalues, color='red')\n",
297 | "plt.title('RSS: %.4f'% sum((results_ARIMA.fittedvalues-log_air_passengers_diff)**2))"
298 | ]
299 | },
300 | {
301 | "cell_type": "code",
302 | "execution_count": null,
303 | "metadata": {
304 | "collapsed": true
305 | },
306 | "outputs": [],
307 | "source": [
308 | "# should we do un-log and then un-diff?\n",
309 | "# or un-diff and then un-log?\n",
310 | "# let's go back and see what we did"
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "execution_count": null,
316 | "metadata": {
317 | "collapsed": false
318 | },
319 | "outputs": [],
320 | "source": [
321 | "predictions_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True)\n",
322 | "print(predictions_ARIMA_diff.head())"
323 | ]
324 | },
325 | {
326 | "cell_type": "code",
327 | "execution_count": null,
328 | "metadata": {
329 | "collapsed": false
330 | },
331 | "outputs": [],
332 | "source": [
333 | "predictions_ARIMA_diff_cumsum = predictions_ARIMA_diff.cumsum()\n",
334 | "print(predictions_ARIMA_diff_cumsum.head())"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {
341 | "collapsed": false
342 | },
343 | "outputs": [],
344 | "source": [
345 | "predictions_ARIMA_log = pd.Series(log_air_passengers.iloc[0], index=log_air_passengers.index)"
346 | ]
347 | },
348 | {
349 | "cell_type": "code",
350 | "execution_count": null,
351 | "metadata": {
352 | "collapsed": false
353 | },
354 | "outputs": [],
355 | "source": [
356 | "predictions_ARIMA_log = pd.Series(log_air_passengers.ix[0], index=log_air_passengers.index)\n",
357 | "predictions_ARIMA_log = predictions_ARIMA_log.add(predictions_ARIMA_diff_cumsum,fill_value=0)\n",
358 | "predictions_ARIMA_log.head()"
359 | ]
360 | },
361 | {
362 | "cell_type": "code",
363 | "execution_count": null,
364 | "metadata": {
365 | "collapsed": false
366 | },
367 | "outputs": [],
368 | "source": [
369 | "predictions_ARIMA = np.exp(predictions_ARIMA_log)\n",
370 | "plt.plot(air_passengers)\n",
371 | "plt.plot(predictions_ARIMA)"
372 | ]
373 | },
374 | {
375 | "cell_type": "markdown",
376 | "metadata": {},
377 | "source": [
378 | "# Know more"
379 | ]
380 | },
381 | {
382 | "cell_type": "code",
383 | "execution_count": null,
384 | "metadata": {
385 | "collapsed": true
386 | },
387 | "outputs": [],
388 | "source": [
389 | "# Seasonal ARIMA\n",
390 | "# http://www.statsmodels.org/dev/generated/statsmodels.tsa.statespace.sarimax.SARIMAX.html\n",
391 | "# Confidence interval for ARIMA \n",
392 | "# http://statsmodels.sourceforge.net/devel/generated/statsmodels.tsa.arima_model.ARIMAResults.forecast.html#statsmodels.tsa.arima_model.ARMAResults.forecast"
393 | ]
394 | },
395 | {
396 | "cell_type": "code",
397 | "execution_count": null,
398 | "metadata": {
399 | "collapsed": true
400 | },
401 | "outputs": [],
402 | "source": []
403 | }
404 | ],
405 | "metadata": {
406 | "anaconda-cloud": {},
407 | "kernelspec": {
408 | "display_name": "Python [Root]",
409 | "language": "python",
410 | "name": "Python [Root]"
411 | },
412 | "language_info": {
413 | "codemirror_mode": {
414 | "name": "ipython",
415 | "version": 3
416 | },
417 | "file_extension": ".py",
418 | "mimetype": "text/x-python",
419 | "name": "python",
420 | "nbconvert_exporter": "python",
421 | "pygments_lexer": "ipython3",
422 | "version": "3.5.2"
423 | },
424 | "widgets": {
425 | "state": {},
426 | "version": "1.1.1"
427 | }
428 | },
429 | "nbformat": 4,
430 | "nbformat_minor": 0
431 | }
432 |
--------------------------------------------------------------------------------
/09c. Spectral Analysis.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import matplotlib.pylab as plt\n",
12 | "%matplotlib inline\n",
13 | "import numpy as np\n",
14 | "from numpy import fft\n",
15 | "import pandas as pd"
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "### Let's use Fourier coefficients as a quick way to determine the principal cosine components of a time series"
23 | ]
24 | },
25 | {
26 | "cell_type": "code",
27 | "execution_count": 2,
28 | "metadata": {
29 | "collapsed": true
30 | },
31 | "outputs": [],
32 | "source": [
33 | "# courtesy of https://gist.github.com/tartakynov/83f3cd8f44208a1856ce\n",
34 | "def fourierExtrapolation(x, n_predict):\n",
35 | " n = x.size\n",
36 | " n_harm = 5 # number of harmonics in model\n",
37 | " t = np.arange(0, n)\n",
38 | " p = np.polyfit(t, x, 1) # find linear trend in x\n",
39 | " x_notrend = x - p[0] * t # detrended x\n",
40 | " x_freqdom = fft.fft(x_notrend) # detrended x in frequency domain\n",
41 | " f = fft.fftfreq(n) # frequencies\n",
42 | " indexes = list(range(n))\n",
43 | " # sort indexes by frequency, lower -> higher\n",
44 | " indexes.sort(key = lambda i: np.absolute(f[i]))\n",
45 | " \n",
46 | " t = np.arange(0, n + n_predict)\n",
47 | " restored_sig = np.zeros(t.size)\n",
48 | " for i in indexes[:1 + n_harm * 2]:\n",
49 | " ampli = np.absolute(x_freqdom[i]) / n # amplitude\n",
50 | " phase = np.angle(x_freqdom[i]) # phase\n",
51 | " restored_sig += ampli * np.cos(2 * np.pi * f[i] * t + phase)\n",
52 | " return restored_sig + p[0] * t"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": 3,
58 | "metadata": {
59 | "collapsed": false
60 | },
61 | "outputs": [
62 | {
63 | "data": {
64 | "text/plain": [
65 | ""
66 | ]
67 | },
68 | "execution_count": 3,
69 | "metadata": {},
70 | "output_type": "execute_result"
71 | },
72 | {
73 | "data": {
74 | "image/png": "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\nDYaY4XQZ2RPdGRKLCRMmMGbMGL766qu41UEi7AG51XX06NHlVa1yw+QyMkRFqlkIRhASF6VU2Ab5\nUILkMI+krsmAEQRDpcIpCAcPxqcelY1NmzZx+eWX06BBA4477jheeuklAC666CLuv//+kv169+5N\nv379+Omnn7jtttuYN28etWrVom7dugD06dOH/v37c9FFF1GrVi1yc3OZNm0a7du3p3bt2jRr1oyh\nQ4eWnG/t2rWkpaXx+uuvk52dTXZ2NiNH+gMiDxw4wN133012djZNmjThnnvuoaioyPUzPPPMMzRv\n3pzDDz+cNm3a8OGHHwKErOvjjz9ecvzrr79OixYtqF+/Pj179mTTpk0l76WlpfHqq6/SsmVL6tat\ny+23317WW146lFIJ96erZUgUdDOq/26+Od61KRsdOwZ+nrlz412j2JDIv5lDhw6pU089VQ0bNkwd\nPHhQ/fbbb+q4445TM2bMUJs3b1YNGzZUs2fPVm+99ZY67rjj1P79+5VSSo0fP16dddZZAee64YYb\nVJ06ddS8efOUUkoVFhaqOXPmqKVLlyqllFqyZIlq1KiR+uijj5RSSq1Zs0aJiLrqqqtUfn6+WrJk\niTriiCPUrFmzlFJKPfbYY6pTp05q27Ztatu2ber0009Xjz/+uFJKqdzcXNW0adOSa7/33ntq8+bN\nSimlpkyZomrWrFny2quujz32mFJKqVmzZqn69eurvLw8deDAAXXHHXeozp07l+wrIupvf/ub2rNn\nj1q3bp064ogj1PTp0z3vqdf37SsvddtrLARDpaLSWgjxWlAZWLhwIdu2beORRx4hPT2do48+mn79\n+jF58mQaNmzI6NGjue6667jnnnt48803qVGjRsjz9ejRg44dOwKQmZlJ586dad26NQBt2rShd+/e\nzLGHkqHD2KtVq0abNm3o06dPSertSZMmMXjwYOrVq0e9evUYPHgwb775put1L7vsMho2bAjAFVdc\nQYsWLViwYEFE92DSpEn07duXk08+mYyMDIYPH868efNYZ0u9O3DgQGrVqkXTpk3p2rUreXl5EZ07\nlhhBMFQqnC7nVFlTOSyBhlHp/0rB2rVr2bBhA3Xr1qVu3bpkZWUxfPhw/vjjDwAuvvhiiouLOf74\n4+nUqVPY8zkjfxYsWMDZZ59NgwYNqFOnDq+++irbtm0reV9EaNKkScnrZs2asXHjRgA2btzIUUcd\n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\nAAAAAElFTkSuQmCC\n",
75 | "text/plain": [
76 | ""
77 | ]
78 | },
79 | "metadata": {},
80 | "output_type": "display_data"
81 | }
82 | ],
83 | "source": [
84 | "x = np.array([669, 592, 664, 1005, 699, 401, 646, 472, 598, 681, 1126, 1260, 562, 491, 714, 530, 521, 687, 776, 802, 499, 536, 871, 801, 965, 768, 381, 497, 458, 699, 549, 427, 358, 219, 635, 756, 775, 969, 598, 630, 649, 722, 835, 812, 724, 966, 778, 584, 697, 737, 777, 1059, 1218, 848, 713, 884, 879, 1056, 1273, 1848, 780, 1206, 1404, 1444, 1412, 1493, 1576, 1178, 836, 1087, 1101, 1082, 775, 698, 620, 651, 731, 906, 958, 1039, 1105, 620, 576, 707, 888, 1052, 1072, 1357, 768, 986, 816, 889, 973, 983, 1351, 1266, 1053, 1879, 2085, 2419, 1880, 2045, 2212, 1491, 1378, 1524, 1231, 1577, 2459, 1848, 1506, 1589, 1386, 1111, 1180, 1075, 1595, 1309, 2092, 1846, 2321, 2036, 3587, 1637, 1416, 1432, 1110, 1135, 1233, 1439, 894, 628, 967, 1176, 1069, 1193, 1771, 1199, 888, 1155, 1254, 1403, 1502, 1692, 1187, 1110, 1382, 1808, 2039, 1810, 1819, 1408, 803, 1568, 1227, 1270, 1268, 1535, 873, 1006, 1328, 1733, 1352, 1906, 2029, 1734, 1314, 1810, 1540, 1958, 1420, 1530, 1126, 721, 771, 874, 997, 1186, 1415, 973, 1146, 1147, 1079, 3854, 3407, 2257, 1200, 734, 1051, 1030, 1370, 2422, 1531, 1062, 530, 1030, 1061, 1249, 2080, 2251, 1190, 756, 1161, 1053, 1063, 932, 1604, 1130, 744, 930, 948, 1107, 1161, 1194, 1366, 1155, 785, 602, 903, 1142, 1410, 1256, 742, 985, 1037, 1067, 1196, 1412, 1127, 779, 911, 989, 946, 888, 1349, 1124, 761, 994, 1068, 971, 1157, 1558, 1223, 782, 2790, 1835, 1444, 1098, 1399, 1255, 950, 1110, 1345, 1224, 1092, 1446, 1210, 1122, 1259, 1181, 1035, 1325, 1481, 1278, 769, 911, 876, 877, 950, 1383, 980, 705, 888, 877, 638, 1065, 1142, 1090, 1316, 1270, 1048, 1256, 1009, 1175, 1176, 870, 856, 860])\n",
85 | "n_predict = 100\n",
86 | "extrapolation = fourierExtrapolation(x, n_predict)\n",
87 | "plt.plot(np.arange(0, x.size), x, 'b', label = 'x', linewidth = 3)\n",
88 | "plt.plot(np.arange(0, extrapolation.size), extrapolation, 'r', label = 'extrapolation')\n",
89 | "plt.legend()"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 4,
95 | "metadata": {
96 | "collapsed": false
97 | },
98 | "outputs": [
99 | {
100 | "data": {
101 | "text/plain": [
102 | ""
103 | ]
104 | },
105 | "execution_count": 4,
106 | "metadata": {},
107 | "output_type": "execute_result"
108 | },
109 | {
110 | "data": {
111 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYQAAAEACAYAAACznAEdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xd8VFX6x/HPg4qKgnRYCVJFKSp9VVTyA3FtCGtBxFVA\nUFcUewNXxZVVsVfYXVTEgogdlQUsRHRlKQpSFRTpRRGkiZKQ5/fHnSQzk0kCySQzSb7v12teuffc\nO3OfuUnmmXPPPeeYuyMiIlIh0QGIiEhyUEIQERFACUFEREKUEEREBFBCEBGRECUEEREB9iIhmNlz\nZrbRzObH2HaTmWWaWfWwsiFmtszMlpjZaWHlbc1svpktNbPH4/cWREQkHvamhjAG+FN0oZmlAN2A\nlWFlzYFeQHPgDGCkmVlo8yhggLs3A5qZWa7XFBGRxCkwIbj758CWGJseA26JKusBjHf3DHdfASwD\nOppZXaCyu88O7fci0LPQUYuISNwVqg3BzM4BVrv7gqhN9YDVYetrQ2X1gDVh5WtCZSIikiT239cn\nmNnBwFCCy0UiIlJG7HNCAJoADYGvQ+0DKcBXZtaRoEZwRNi+KaGytUD9GOUxmZkGWBIRKQR3t4L3\nim1vLxlZ6IG7L3T3uu7e2N0bEVz+aePuPwITgQvNrKKZNQKaArPcfQOw1cw6hpLIpcC7+R3Q3ZPq\ncffddyc8BsVUtuJSTIop3o+i2pvbTscBXxDcGbTKzPpHf3aTkywWAxOAxcAkYJDnRHk18BywFFjm\n7pOLHL2IiMRNgZeM3L1PAdsbR63fD9wfY78vgWP2NUARESkZ6qm8l1JTUxMdQi6Kae8lY1yKae8o\nppJj8bjuFG9m5skYl4hIMjMzvAiNyoW5y0hEkkzDhg1ZuXJlwTtKmdCgQQNWrFgR99dVDUGkDAh9\nM0x0GFJC8vp9F7WGoDYEEREBlBBERCRECUFERAAlBBERCVFCEBERQAlBRERClBBEpFgtX76cGjVq\nMG/ePADWrVtH7dq1mT59eoIjk2hKCCJlnFl8H/uqcePGPPjgg/zlL39h165d9O/fn/79+3PKKafE\n/81KkahjmkgZkF/HtMJ8iOensP+aPXv2ZPny5VSoUIHZs2dzwAEHxDewckQd00SkVBs4cCCLFi1i\n8ODBSgZJSjUEkTIg2Yeu2LlzJ8cddxxdunThP//5DwsWLKBq1aqJDqvUKq4aghKCSBmQ7AlhwIAB\n7Nq1i3HjxnHllVfyyy+/8NprryU6rFJLl4xEpFSaOHEiU6dOZeTIkQA8+uijzJ07l1dffTXBkUk0\n1RBEyoBkryFIfKmGICIixUoJQUREACUEEREJUUIQERFACUFEREIKTAhm9pyZbTSz+WFlD5rZEjOb\nZ2ZvmlmVsG1DzGxZaPtpYeVtzWy+mS01s8fj/1ZERKQo9qaGMAb4U1TZVKClu7cGlgFDAMysBdAL\naA6cAYw0yx5JZRQwwN2bAc3MLPo1RUQkgQpMCO7+ObAlquwjd88Mrf4PSAktnwOMd/cMd19BkCw6\nmlldoLK7zw7t9yLQMw7xi4hInMSjDeEyYFJouR6wOmzb2lBZPWBNWPmaUJmISFL69NNPqV+/fqGf\nf9VVV/GPf/wjjhEVv/2L8mQzuwNId/e490EfNmxY9nJqaiqpqanxPoSIJLGxY8fy7LPP8tlnnyUs\nBtvLscNjxTpq1KjiCitbWloaaWlpcXu9QicEM+sHnAl0CSteC4Sn1JRQWV7leQpPCCJS/rh7gR/I\nmZmZVKiQ+Jsl9ybW4hD9Zfmee+4p0uvt7Zm00CNYMTsduAU4x91/D9tvItDbzCqaWSOgKTDL3TcA\nW82sY6iR+VLg3SJFLiKlxvr16zn//POpXbs2TZo04emnnwbgrLPO4uabb87er3fv3gwcOJBvvvmG\nq666ihkzZlC5cmWqV68OQP/+/Rk0aBBnnXUWlStXJi0tjUmTJtG2bVsOO+wwGjRoEPGhuHLlSipU\nqMDo0aOpV68e9erV45FHHsnevnv3bq6//nrq1atHSkoKN9xwA+np6THfw4gRI2jatClVqlShVatW\nvPPOOwD5xnrXXXdlP3/06NEceeSR1KxZk549e7J+/frsbRUqVOBf//oXzZo1o3r16lxzzTVFPeWF\n4+75PoBxwDrgd2AV0J+gsXgl8FXoMTJs/yHAd8AS4LSw8nbAgtBznyjgmC4iey+Z/2cyMzO9Xbt2\nPnz4cM/IyPAffvjBmzRp4lOnTvUNGzZ4nTp1fNq0af7yyy97kyZNfOfOne7u/sILL/jJJ58c8Vr9\n+vXzqlWr+owZM9zd/ffff/dPP/3UFy5c6O7uCxYs8Lp16/q7777r7u4rVqxwM/M+ffr4rl27fMGC\nBV6rVi3/+OOP3d39zjvv9BNOOME3bdrkmzZt8hNPPNHvuusud3dPS0vz+vXrZx/7jTfe8A0bNri7\n+4QJE/yQQw7JXs8r1jvvvNPd3T/++GOvWbOmz5s3z3fv3u2DBw/2U045JXtfM/Pu3bv7tm3bfNWq\nVV6rVi2fMmVKnuc0r993qLzAz/W8HoV+YnE+kvmPWyQZFfg/E8x8WfRHIcycOdMbNGgQUXb//ff7\nZZdd5u7ub731ltevX99r1arlX3zxRfY+eX3I9u3bN9/jXX/99X7jjTe6e05CWLp0afb2W2+91QcO\nHOju7k2aNPHJkydnb5syZYo3atTI3XMnhGitW7f2iRMn5htrVkIYMGCA33bbbdnbduzY4QcccICv\nXLnS3YOEEP7ee/Xq5SNGjMjz2MWVEBJ/8U1Eil+8UkIhrFy5krVr11K9enWqV69OtWrVuP/++/nx\nxx8BOPvss9mzZw9HHXUUJ5xwQoGvF33nz6xZs+jSpQu1a9ematWq/Otf/2LTpk3Z282MlJSU7PUG\nDRqwbt06ANatW8cRRxwRc1u0F198kTZt2lCtWjWqVavGokWLIo6Tn3Xr1tGgQYPs9UMOOYQaNWqw\ndm1OU2qdOnWylytVqsSOHTv26rXjSQlBRIpV/fr1ady4MZs3b2bz5s1s2bKFrVu38t577wEwdOhQ\nWrRowfr16xk/fnz28/JqpI0u79OnDz179mTt2rX88ssvXHnllVlXGoDgKsjq1Tl3w69atYrDDz8c\ngMMPP5yVK1dmb1u5cmX2tnCrVq3iiiuuYOTIkWzZsoUtW7bQsmXL7OMU1KAcfZydO3fy888/RySq\nZKCEICLFqmPHjlSuXJkHH3yQ3377jT179rBo0SLmzJnD9OnTGTt2LC+99BIvvPACgwcPzm5srVOn\nDmvWrMmzkTfLjh07qFatGgcccACzZs1i3Lhxufa599572bVrF4sWLWLMmDH07t0bgIsuuojhw4ez\nadMmNm3axL333ssll1yS6/k7d+6kQoUK1KxZk8zMTMaMGcPChQuztxcU60UXXcSYMWOYP38+v//+\nO0OHDuX4448vUj+H4qCEICLFqkKFCrz//vvMmzePRo0aUbt2bS6//HLWr19Pv379eOaZZ6hbty4n\nnXQSAwcOpH///gB06dKFli1bUrduXWrXrp3n648cOZI777yTww47jOHDh3PhhRfm2qdz5840bdqU\nbt26ceutt9K1a1cA/va3v9G+fXuOPfZYjjvuONq3b88dd9yR6/nNmzfnpptu4vjjj6du3bosWrSI\nk046KXt7QbF27dqVe++9l3PPPZd69erxww8/5FsbSsQtrKApNEXKBE2hGdvKlStp3Lgx6enpSdFf\nIV40haaISCEoUe49JQQRKdMSdfmlNNIlI5EyQJeMyhddMhIRkWKlhCAiIoASgoiIhBRpPgQRSQ4N\nGjRQ42k5Ej4MRjypUVlEyofdu+GOO2DcOHj+efhT2ZvWvaiNyqohiEjZt2oV9OoFderA119DzZqJ\njigpqQ1BRMq2yZOhY0c47zx45x0lg3yohiAiZZM7/P3vMHo0vP46nHxyoiNKekoIIlL2pKfDFVfA\nkiXw5ZfBpSIpkBKCiJQtO3fCBReAGXz8MRxySKIjKjXUhiAiZcdPP8H//R/UrRu0FygZ7BMlBBEp\nG5Yvh06d4LTT4Lnn4IADEh1RqaOEICKl39y5QaPx9dfD8OHB5SLZZ2pDEJHS7aOPoE8f+Oc/4dxz\nEx1NqaYagoiUXi+9BBdfDG++qWQQBwUmBDN7zsw2mtn8sLJqZjbVzL41sylmdljYtiFmtszMlpjZ\naWHlbc1svpktNbPH4/9WRKTccIdhw+Cuu+CTT9THIE72poYwBoge9ON24CN3Pwr4BBgCYGYtgF5A\nc+AMYKTljLg1Chjg7s2AZmZW9gYSEZHit2VLcFvppEkwYwa0bJnoiMqMAhOCu38ObIkq7gGMDS2P\nBXqGls8Bxrt7hruvAJYBHc2sLlDZ3WeH9nsx7DkiInsnLQ1at4Z69WD69OD2UombwjYq13b3jQDu\nvsHMaofK6wEzwvZbGyrLANaEla8JlYuIFGzBgmAYipkzYdQoOOusREdUJsXrLqO4j1U9bNiw7OXU\n1FRSU1PjfQgRSVYZGfDNN/Cf/8C77wZ9DAYPhrFjoVKlREeXNNLS0khLS4vb6+3VfAhm1gB4z92P\nDa0vAVLdfWPoctA0d29uZrcD7u4jQvtNBu4GVmbtEyrvDXR296vyOJ7mQxApL7Zvh3nzgr4E8+bB\n/PnBGER/+AN06wZnnw2nngoHHpjoSJNeSc2HYKFHlolAP2AE0Bd4N6z8FTN7jOCSUFNglru7mW01\ns47AbOBS4MnCBi0ipdyWLcEto++8A7NnBw3DbdrAH/8YDErXqhUcemiioyx3CqwhmNk4IBWoAWwk\n+Mb/DvA6UJ/g238vd/8ltP8QYACQDlzn7lND5e2AF4CDgEnufl0+x1QNQaQsWr0aHngAXn0Vzjwz\nuFvo1FM15lCcFLWGoCk0RaT47d4Njz4KDz8Ml18O114bXBKSuNIUmiKS3KZODRqEmzUL7hJq0iTR\nEUkelBBEpHisWgU33ghffQVPPAHduyc6IimAxjISkfj67Te47z5o2xaOOQYWLVIyKCVUQxCR+HCH\n8eNhyJDgjqFZs6Bx40RHJftACUFEiiYzEz74AO69N0gKY8dC586JjkoKQQlBRAonPT2oEYwYARUr\nBjWD886DCroSXVopIYjIvvn112CKyocfDi4JPfpo0KNYs5SVekoIIrJ3tmyBZ56Bp54K5i6eMCHo\nWSxlhup2IpK/devg5puD/gPffx8MQf3WW0oGZZASgojEtmxZ0Ku4VSvYswe+/hrGjIHmzRMdmRQT\nXTISkRzu8PnnQUeyTz+Fq6+GpUuhZs1ERyYlQAlBRGDTJnj7bfjnP4PhqK+9Fl54QSOOljMa3E6k\nvHEPJpyZMwe+/DIYX2jePDj9dOjbN/ipW0dLJY12KiL5S0+HL74IGoM/+yxIAoceCu3bQ7t2wc9T\nTtFMZGWAEoKIxLZlS9BX4Pnng0npu3QJPvg7doTatQt+vpQ6Gv5aRCK5B9f/b70VevaEadPg6KMT\nHZWUAkoIImXJb7/BZZfBwoXwySfBaKMie0kJQaSs2Lo1GGb68MODkUYPOijREUkpozYEkbIgPR3O\nOgsaNYJRo3SXUDlV1DYE/dWIlHbucM01sP/+wVhDSgZSSLpkJFLaPfII/O9/QQ/j/fUvLYWnvx6R\n0uztt+Hxx2HGDKhcOdHRSCmnhCBSWs2ZA1dcAZMnQ/36iY5GyoAiXWw0sxvMbKGZzTezV8ysoplV\nM7OpZvatmU0xs8PC9h9iZsvMbImZnVb08EXKqVWroEcPGD066G0sEgeFvsvIzA4HPgeOdvfdZvYa\nMAloAfzs7g+a2W1ANXe/3cxaAK8AHYAU4CPgyFi3E+kuI5F8bNsGJ50UjDt0002JjkaSSKLvMtoP\nOMTM9gcOBtYCPYCxoe1jgZ6h5XOA8e6e4e4rgGVAxyIeX6R8SU+H3r3hxBPhxhsTHY2UMYVOCO6+\nDngEWEWQCLa6+0dAHXffGNpnA5A1aEo9YHXYS6wNlYnI3sjMDHohmwXTWGoOY4mzQjcqm1lVgtpA\nA2Ar8LqZXQxEX+sp1LWfYcOGZS+npqaSmppaqDhFygT3oEbwww8wdSoccECiI5IkkJaWRlpaWtxe\nryhtCOcDf3L3y0PrlwDHA12AVHffaGZ1gWnu3tzMbgfc3UeE9p8M3O3uM2O8ttoQRLLs2QPXXx/0\nM5g2DapWTXREkqQS2YawCjjezA4yMwO6AouBiUC/0D59gXdDyxOB3qE7kRoBTYFZRTi+SNm3ZQuc\ndx4sWKBkIMWuKG0Is4A3gLnA14AB/wZGAN3M7FuCJPFAaP/FwASCpDEJGKRqgEge3OGdd6BNG2jQ\nAKZMUTKQYqfB7USSydat8P77QaPxjh3w2GPQrVuio5JSQjOmiZRm6enBOEQffhg8Fi4M+hhceWUw\nlPV++yU6QilFlBBESputW+G994JxiD76CJo2DWoB3bpBp06ax0AKTQlBpLRYuhSefBLGjQtqAX/+\nM5x9NtSqlejIpIzQnMoiyW79ehg2DN56C/761+COoXrqkynJRzNpiBSXPXvgiSeCeY2rVAlqCPfe\nq2QgSUs1BJHisGgRDBwIFSvCF19As2aJjkikQKohiMRTZiY8/DCkpgajkU6bpmQgpYZqCCLxsnp1\nkATS02H2bGjYMNERiewT1RBE4mH8+GCimm7dIC1NyUBKJdUQRIpi2zYYNCioEUyaBO3bJzoikUJT\nDUGksObPDxJApUrw1VdKBlLqKSGIFMYLL0DXrnDXXfDvf8MhhyQ6IpEi0yUjkX2xezdcfXUwN0Fa\nGrRsmeiIROJGCUFkb23fDuefH4w1NHs2HHpooiMSiStdMhLZGxs3wv/9X3D30JtvKhlImaSEIFKQ\n774LRiHt3h3++U/YXxVrKZuUEETyM2cOnHIK3Hor3H03WKEHkhRJevqqI5KXKVPgkkvg2WfhnHMS\nHY1IsVMNQSSWl16CSy8N5jVWMpByQjUEkXDu8MADQVtBWho0b57oiERKjBKCSJb09GACm7lzYcYM\nOPzwREckUqJ0yUgEYNWqoOfxjz/C9OlKBlIuKSHIXnnkkeDOyw8/THQkceYOr78OHTrAmWcGbQbq\nYyDllBVlMnszOwx4FmgFZAKXAUuB14AGwAqgl7tvDe0/JLRPBnCdu0/N43W9KHFJfP30E9SunbOe\nmVkG7r50D2Yyu/vuYM7jMWOgY8dERyVSJGaGuxf6v7OoNYQngEnu3hw4DvgGuB34yN2PAj4BhoQC\nbQH0ApoDZwAjzUr9x0q5sHZt5Pr8+YmJo8h27w76Ffz979C2bTCZzfnnw9dfKxmIUIRGZTOrApzs\n7v0A3D0D2GpmPYDOod3GAmkESeIcYHxovxVmtgzoCMwsdPRSInbujFyfNAmOOy4xsey1zZuDxuG5\nc2HevCCLffcdNGoEp58Ojz4adDjbb79ERyqSNIpyl1EjYJOZjSGoHcwBrgfquPtGAHffYGZZFxvq\nATPCnr82VCZJbtu2yPUlSxITR4HWroUXX4SJE2Hx4iBrtW4NXbrADTdAixZw8MGJjlIkaRUlIewP\ntAWudvc5ZvYYQU0g+uJ/oRoDhg0blr2cmppKampq4aKUIotOCDt2JCaOPC1eDPffDx98ABdcAPfc\nE0xyX7FioiMTKVZpaWmkpaXF7fWKkhDWAKvdfU5o/U2ChLDRzOq4+0Yzqwv8GNq+Fqgf9vyUUFlM\n4QlBEmv79sj1pEkI27cHH/5jx8LNN8OTT0K1aomOSqTERH9Zvueee4r0eoVuVA5dFlptZs1CRV2B\nRcBEoF+orC/wbmh5ItDbzCqaWSOgKTCrsMeXkpN0NQR3ePXVoBfxzz/DokVw221KBiJFVNSeytcC\nr5jZAcByoD+wHzDBzC4DVhLcWYS7LzazCcBiIB0YpHtLS4ekSgiLFgUzlm3dChMmwIknJjAYkbKl\nSAnB3b8GOsTYdGoe+98P3F+UY0rJS4qEsHVrcLvoSy/BsGFw5ZW6Q0gkztRTWcjMhFtuCeZ/Wbo0\n9/aEtiGkp8PTT0OzZkFSWLQIBg1SMhApBhrcTnj6aXj44WC5Vi14/vnI7dE1hOgEUSzS02H8eBg+\nHBo0CMbMOPbYEjiwSPlVpKEriouGrihZ0f3Fo0/9GWfA5MmRZenpxTST5K+/Bhnp4YehcWMYMgRO\nPbUMjJUhUvyKOnSFagjl3NatketNm+beJ1aNYOdOOOywOAayZQs88ww89VTQUPzaa/DHP8bxACJS\nELUhlHObN0euH3hg7n2iLxlBHNsR1q0L+hA0aQLffx9MSvP220oGIgmghFDO/fJL5HqsD/roWkRe\n++2TpUvh8suhVSvYsycYb2jMGM1QJpJAumRUzkV/2Me6PPTzz7nLCt2w/OWXwRSVaWlBf4KlS6Fm\nzUK+mIjEkxJCOVdQDeH333OPdhprv3xlZgZDpD7+OHz7Ldx0U1Ab0EQ0IklFCaEc2L07mOSmXoyx\nZaMTwu7dwSNrXLhYtQPYy4SwZk0wG9moUVC5Mlx3HfTurUHnRJKUEkIZt20btGsXTAUwciRcdVXk\n9rzaB6pXD5bzSgi5Lhnt2RNc/pkzJ7gsNGNGcNDu3YPbSDt10q2jIklOCaGM+8c/gs9lgFtvzZ0Q\nomsIsHcJ4ec1u2DK9KAt4L//DSaiqV0b2rcPMtADDwRJQLUBkVJDCaGMGzMmZznWZZ5YCSH82390\nQjictQzhfi67axx0aBXMO3DnnUEi0GijIqWaEkIZlpkZtB1kifVlPa8aQpashFCBPdzCQ9zCQzzL\nQIae+TWPv1k/95NFpNRSQijDtmyJXI/1BT5WG0J0DaEam3mD86l8SCZtd37FKhpwaozOaiJSuqlj\nWimXkZG7t3GWH3+MXN/bS0bh+2WsWMPnnMRXtOXxsz9mFQ2AoIOxiJQtSgil2MSJkJICNWrAI4/k\n3h5+uQiC/gSZmZFl0bUICEsI27Zx8bgzeZFLuYWHObZNzpDT69cXLXYRST5KCKXYpZfCxo3B8r//\nnXt7dEKAYDDRcNG1CAhdMsrIYOfZFzJ5x0mM4DYqVIBevXJGON2yBXbtKlL4IpJklBBKqd27I6//\nx/rGHishhF8OysyMnRA2/+xw3XVs3uxcy5OAccYZ0KgR1KmT/+uLSOmlhFBKRSeAHTuC9oRwsT7s\nwxPCli25nwPQ4sMnYPp0Xjp7AntC9x20bh1sC2+YjnW5SURKLyWEUmrNmsh199wf0LG+wYePS5R1\nuSlcdybSefZD8P77fPdjlezy+qE7TJUQRMouJYRSKjohQO5OZAVdMopOCG34iucYwJ2t3oEGDSKO\nkZIS/AxPCJdfDm++uW9xi0jyUkIopdauzV22aVP+65B3Qjg+ZQ3v0oO/8k/+u7sDAKtX52yPlRC+\n+04JQaQsUUIopWLVEKITQL63lJKTECqzjVe2decpBvMW5/HTT0GD9Tff5OybdcmoatXI18tKFCJS\n+hU5IZhZBTP7yswmhtarmdlUM/vWzKaY2WFh+w4xs2VmtsTMTivqscuyH3+Ehx6CmTNjb4/VMWxf\nE8L69XAgv/EOPfmpyfE8xC3Zrx3+wX/wwTk1g+jezvU1eoVImRGPGsJ1wOKw9duBj9z9KOATYAiA\nmbUAegHNgTOAkWYaDzkvAwcGo5N27hz5TT1LrN7J0Qkhv17ImzbBwyMyeJWL+IlafH/D0xx6aOxf\nR8OGOSNXRycE1RBEyo4iJQQzSwHOBJ4NK+4BjA0tjwV6hpbPAca7e4a7rwCWAR2Lcvyy7L33gp+/\n/x403kYrKCFkZsZOCDt3Bnck/emUXbzOBRzEb1zCS7Rpvx+1asWOpWXLnGXVEETKrqLWEB4DbgE8\nrKyOu28EcPcNQO1QeT0grJmStaEyiRI9ZeXXX+fep6CEsG1b8MEf7ZdfYOvC1Ty1pCu/cRA9eYd0\nKtKsGdStGzue/BKCaggiZUehRzs1s7OAje4+z8xS89k1xsdSwYYNG5a9nJqaSmpqfocoW1atilzf\nvj0YJuLgg3PKCkoIsWoHFdjDkZ+O4dB/38FEbuBBbsWpQOvWsN9+safYBDjyyJzl6CG0a9dGRBIk\nLS2NtLS0uL1eUYa/7gScY2ZnAgcDlc3sJWCDmdVx941mVhfI6i+7Fgi/wJASKospPCGUN9EJAYI7\ngho2DJYzMmIPWx2eEMIblGvyE+fxJtfyJJmLa7Dk8UmM6Ncue/vNNwc/Dz88djzHHpuzHF1DqKD7\n1EQSJvrL8j333FOk1yv0v7O7D3X3I9y9MdAb+MTdLwHeA/qFdusLvBtangj0NrOKZtYIaArMKnTk\nZdjKlbnLNmzIWY717R/COqbt2oV9OJUHuYWvaMMyjqQrHzOYp+iTMp3VtXKSQfv2cPHFwXKsGsIN\nN8AxxxCx/5lnBoPcPfXUvr0vEUluxTFBzgPABDO7DFhJcGcR7r7YzCYQ3JGUDgxyj3WVWwpKCOHf\n/qtWDRJELX7krLXvwOlvweefk1K/NTvoxjU8jbfvyIw5BwBQc0Nkj+bwy0HRNYRZs6BDh8gyM/jg\ng2DU1EqVCvkGRSQpxaXC7+6fuvs5oeXN7n6qux/l7qe5+y9h+93v7k3dvbm7T43HsUujZcugXz8Y\nPTr29lh9DMITQnj7wZl1v+RFLuVbjuKPu6aRcellbPtmHZc0/Jy/czdf0ImmzQ/IvrSzaVNkp7Ya\nNXKWo2sI+TUYKxmIlD26ApwAt90GY8fCFVfA7Nm5t8cagygrIWzbBo89Bk1Zxuucz+M/9OD7SsfQ\nhO/pw6v83LUX5/ylCpMn5zy3Ro3IYauHDs1Zrl49Z7lmzchjqsFYpHxRQkiAt9/OWY4101msYauz\nEkLfC3+j1Wt/YwYn8CXtuLn7Ul474ha2EHyyr1sHn34a+dwjj4Q//CF2LOE1hGbNchLHiScGdx6J\nSPmhhJBgCxbkLsuzhvD559w3uQ3NWcIxLOABhpDSrFLEN/tYr9e9e953EIUnhAMPhEmT4O9/h5de\n2qe3ISJlQHE0Kks+tm+PXF+6NLiNdP+w30R0QqjI71ww8w78wle5g6d4m3MBqFIFBg2CxWEDh/Tt\nG/ncDh0ihPonAAAP3UlEQVSC3sR51RCiawFt2wYPESl/VEMoYdEznWVkRDYi//prZE/llixkFh2p\nsXU5GyZ/nZ0MAN5/P2gIzqtDGcCoUcHPvBJCu3axy0Wk/FFCKGGx7iD64Yec5azagZHJ7Qc9Thqp\nPMF19Mh4kw0ZOdeGWrWCk08OlvMaT2jQoJwP/FiXjB5/PPK2UxEp33TJqIRF1xAAVqwIRjWFYLjr\nuqxnLH2pU2E7XSrNZMGvTSA9uLyUJfwOoLxuDw3fJ7qGcOONcN11hXoLIlJGqYZQwvKrIQwfDqMu\nnMaXtGMGJ3DbCZ/xW70m2fv17p3znPAP+7xqCBkZOcvRNYTWrfcxcBEp85QQSlheNQQyMzn4sfsY\nRx/6MpZh3MOxbffPcwTSvakhXHRRznJ0DeG44/YlahEpD5QQ4mzRIjj1VBg8OPIbepZYNYSNy7bh\n3c/h+M0f0IHZfEQ3UlKCCXLySgjhI59GNyqfey689Ra0aJFTFt4xDeDoo/fu/YhI+aGEEGfDh8PH\nH8PTTweNttGiawh1Wc9Dszuzq2Z9UkljLcHX/WXLgp7Ded1BdOihOcsHHhg0MkPQ8/jll+HPf47c\nf//9g97RHTsG26OHsRYRsWQcX87MSu24d9GTgu7ZEzlE9NFHw7ffBstHspTJnM7zNoAzpg/lpJOD\nJx97bM6kOE89BddeG/maBx4YTKuZNRw2wLx5wdhIF1wA5WjqCBEJY2a4e6GnJlYNIc6iv3mvXh25\nnnXJqCMz+ZTODOdv/MPvyE4GAEcckbN/48aRz+/aFb7/PjIZQNBI/MwzSgYiUnhKCIWQmRm7/Jdf\nYPfuyLLwW0V37Ah6Kp/BJN6jO48c/SxjuCzX64Q3GEcnhB498u+IJiJSWEoI++ihh4JLNn365N4W\nax6DZcuCn+7w/PPQjzE8z2VcWXciG9ufFfMYRx2VsxxdE9Ck9iJSXJQQ9sHChcGdPxkZ8OqrsHx5\n5Pb8EsKIB5wN193HXfydznzKhobH5/qwh6B2cP75OevhdxMBNGhQpLcgIpInJYR98MQTkevffRe5\nHj4ERZalS4GMDJo8djW9mEAn/stSjuLCC6FRo8h9O3UK+iREXyZ6+umgVnLBBepQJiLFR0NX7IPP\nP49cj64hhLcXZFn3zTa8+4VU35LJKUxnO1V47z04+2yYNi1y32bNctcIAK6+Gi6/XLeKikjxUg0h\nzJ49MHdu0PgbbfPm4FbPcNEJIXp7Kxbw8vIT2FrlCE7PeJ/tVKFSJTgr1HSwL+0DSgYiUtyUEMIM\nGRLMBdCqFfz2W075l1/Co4/m3v/773OWN28O+gIAVGAPV/M0n9CFh7iFahP+SQbBJPeNG+f0VYhO\nALVqxfHNiIjsI10yCtmyJbiDCILG4S++gC5d4JVX4C9/if2crITw1ltw3nnBkNWnM4X77A72q1yJ\nTtv+yzKaRTwnfEKa/aPO/oEHxunNiIgUghJCyLhxketZDcQffJD3c779Fvbs2MXsR+dwPx9wLm+x\nk0N4JWUI20+/gGWjc3cYPPXUyPX+/WHMGDjkkNzDTYiIlCQlBII+AqNHR5Zl3UG0alVOWR02cFrN\nuRz92zya7JjHsb/Nx2qu4ILfmzOJM/kLLzObDjx+k8Uc2A7gkksi1x99NBhfqEMHIuZGFhEpaYUe\ny8jMUoAXgTpAJjDa3Z80s2rAa0ADYAXQy923hp4zBLgMyACuc/epebx2iY5lNH9+7uGgzz8fXn8d\nTvnDMk7d8BI9eJeGFVbjbdvy8abWvL2iNV9zHHePO4prb6qYPWhdhw4wY0YwwN2f/pTzek2aBG0M\n4YPSiYjEUyLHMsoAbnT3lsAJwNVmdjRwO/CRux8FfAIMCQXaAugFNAfOAEaaRQ8Flxhz5+YuO2je\n/8jsfg5vbOhEJX5lECM5aPtPVJ39EbN6Pcwr/IWFHMOMORUjRjD97LOgneDYYyNfr317JQMRSW6F\nTgjuvsHd54WWdwBLgBSgBzA2tNtYoGdo+RxgvLtnuPsKYBnQsbDH31fTpweDvy1alHtb+O2jtdnI\nGPrxwHfns6nDmTRkBbfwMMvrduLASkGLcNZQ0xB591GNGjkNw9HzD1SuHKc3IiJSTOJy26mZNQRa\nA/8D6rj7RgiSBpA1VFs9IHzsz7WhsmI3eXIwZ/E11wTX67OGmHCHt98OhpjejwwG8yQLacVP1OJo\nllDn7r+yi0pA5Aik4WMNhatRI2fZLHKCmjPOiPObEhGJsyI3KpvZocAbBG0CO8ws+uJ/oRoDhg0b\nlr2cmppKahHGdX799ZzlX3+F8ePhttuCu3sGDICT+IynuYafqcEl9T9lyuoWuV4jfJiJZs1ybQZy\nd1R7/vmgh3GbNtCzZ+zniIgUVlpaGmlpafF7QXcv9IMgoUwmSAZZZUsIagkAdYEloeXbgdvC9psM\n/DGP1/V4yMhw37PHvXlz96A+EDyOPz7Y3uzQtT6WS3wVKd6L8Q6Zft99kfuC+2GHuf/3v5GvHb0P\nuLdqFZewRUQKJfTZWejP9KJeMnoeWOzu4cO+TQT6hZb7Au+Glfc2s4pm1ghoCswq4vHztGZNcGfP\nfvvBkiWR2xb8byerBtzDFzuOYR2H05wlTOBCKlSwXJ3QKlWCn3+GE08s+Jj33BO/+EVESlqhE4KZ\ndQIuBrqY2Vwz+8rMTgdGAN3M7FugK/AAgLsvBiYAi4FJwKBQRiuS9PRg8Ld27eCmm3Imr3niidzD\nUVdiJ4N5km84ipljv6EdXzKEB9hJcPvPoEG5h5OoVi2yd3GWoUNzll98Mbh19dxzi/puREQSp9TP\nqTx2LPTrF7l+6aXBdf6suQhq8SPX8DSDbBRp3pkR3MYcOmQ/54Ybgn4HJ5wQNAZfdlnQvgDB0NNX\nX537uNu3B3ctNWwIvXsX7n2KiMRTUfshlPqEMHAgPPdczvrJJwe3mLZsCbsWL+cmHuEiXmXmEb3Y\n+debuGDokRHP798/aPwNt24d9O0LVasG3/5jDUktIpJsynxC2LAhGG30mGMib/3MctxxweWacBun\nzGPa6SPo6h/yL65k9EHX8smiOuzeDc2bR+67bZv6CIhI2VDUhJDUYxktXx584O/YEcwHMHNmzoxh\nu3fDTz+FdzRzTuYzbucB9uvxNbP9Bi7nX2ynCut/gLp1g3uBoikZiIgEkno+hNGjcyar2b0bHnss\nWF6zBlJSgseePc5ZvM9/6cRzDOBt/ky9377nEW5mO1W44oogGUDQPnDhhTmvf9VVJft+RESSWdJe\nMurTx3MNSX3wwcElpIcegvuG7+F83mAo9wFwH0N5g/PJJOeWoPbtg0HmqlTJeY2VK6Fbt2D544/z\nn6VMRKQ0KbNtCHl1cP7PM8v5YdhYzv7peVZxBPcxlEmcSZ8+liuBLFwYNC5Hy3rLyTG0nohIfJTp\nhFCBPTRjKW2YS3vmcDqTqcHPTKAXo7mcBeQMKZqWBtGjW2RkxO5DICJSFpXZhPA5J3IcX7OBuuxu\n2YaXF7XhQ7rxJe2I7mDduHHQGzl6CsokfGsiIsWmzCaEVD5hfZ02nHhmVf7976Bh+OefI/f7z39g\nzx44/vhgpNGLL86ZCjM1FaZNK/HQRUQSpswmhNmznfbtc8o6dw46nGW58koYNSqyHWD16mB46127\n4KOPiHi+iEhZV2YTQnRcb70F550XLA8YAM8+G/u5GRnB+EbqXSwi5U25SQjucP/9wW2j//iHJqQX\nEYlWbhKCiIjkr6gJIal7KouISMlRQhAREUAJQUREQpQQREQEUEIQEZEQJQQREQGUEEREJEQJQURE\nACUEEREJKfGEYGanm9k3ZrbUzG4r6eOLiEhsJZoQzKwC8DTwJ6AlcJGZHV2SMRRWWlpaokPIRTHt\nvWSMSzHtHcVUckq6htARWObuK909HRgP9CjhGAolGf8AFNPeS8a4FNPeUUwlp6QTQj1gddj6mlCZ\niIgkmBqVRUQEKOHhr83seGCYu58eWr8dcHcfEbWfxr4WESmEUjMfgpntB3wLdAXWA7OAi9x9SYkF\nISIiMe1fkgdz9z1mdg0wleBy1XNKBiIiySEpZ0wTEZGSl1SNysnSac3MVpjZ12Y218xmhcqqmdlU\nM/vWzKaY2WElEMdzZrbRzOaHleUZh5kNMbNlZrbEzE4rwZjuNrM1ZvZV6HF6CceUYmafmNkiM1tg\nZteGyhN2rmLENDhUnrBzZWYHmtnM0N/1AjO7O1SeyPOUV0wJ/ZsKHadC6NgTQ+sJ/d8Li2luWEzx\nPU/unhQPguT0HdAAOACYBxydoFiWA9WiykYAt4aWbwMeKIE4TgJaA/MLigNoAcwluAzYMHQurYRi\nuhu4Mca+zUsoprpA69DyoQTtVEcn8lzlE1Oiz1Wl0M/9gP8R9A1K9N9UrJgSep5Cx7oBeBmYGFpP\n6HnKI6a4nqdkqiEkU6c1I3ftqQcwNrQ8FuhZ3EG4++fAlr2M4xxgvLtnuPsKYBnBOS2JmCA4Z9F6\nlFBMG9x9Xmh5B7AESCGB5yqPmLL63CTyXP0aWjyQ4MPCSfzfVKyYIIHnycxSgDOBZ6OOnbDzlEdM\nEMfzlEwJIZk6rTnwoZnNNrOBobI67r4Rgn92oHaCYqudRxzR528tJXv+rjGzeWb2bFhVusRjMrOG\nBDWY/5H376xE4wqLaWaoKGHnKuuSA7AB+NDdZ5Pg85RHTJDYv6nHgFvISU6Q+L+nWDFBHM9TMiWE\nZNLJ3dsSZOOrzexkcv8SkqU1PhniGAk0dvfWBP/UjyQiCDM7FHgDuC70rTzhv7MYMSX0XLl7pru3\nIahBdTSzliT4PMWIqQUJPE9mdhawMVTDy++e/hI7T/nEFNfzlEwJYS1wRNh6SqisxLn7+tDPn4B3\nCKpaG82sDoCZ1QV+TERs+cSxFqgftl+JnT93/8lDFy6B0eRUTUssJjPbn+CD9yV3fzdUnNBzFSum\nZDhXoTi2AWnA6STJ31R4TAk+T52Ac8xsOfAq0MXMXgI2JPA8xYrpxXifp2RKCLOBpmbWwMwqAr2B\niSUdhJlVCn2rw8wOAU4DFoRi6RfarS/wbswXKIaQiPxGkFccE4HeZlbRzBoBTQk6/hV7TKF/jizn\nAgsTENPzwGJ3fyKsLNHnKldMiTxXZlYz65KCmR0MdCNo20jYecojpm8SeZ7cfai7H+HujQk+hz5x\n90uA90jQecojpkvjfp6KoyW8sA+CbyvfEjSA3J6gGBoR3OE0lyAR3B4qrw58FIpvKlC1BGIZB6wD\nfgdWAf2BannFAQwhuJtgCXBaCcb0IjA/dN7eIbjWWpIxdQL2hP3evgr9LeX5OyvuuPKJKWHnCjgm\nFMe8UAx3FPS3ncCYEvo3FXaszuTc0ZOw85RPTHE9T+qYJiIiQHJdMhIRkQRSQhAREUAJQUREQpQQ\nREQEUEIQEZEQJQQREQGUEEREJEQJQUREAPh/gbmgqMcEMLAAAAAASUVORK5CYII=\n",
112 | "text/plain": [
113 | ""
114 | ]
115 | },
116 | "metadata": {},
117 | "output_type": "display_data"
118 | }
119 | ],
120 | "source": [
121 | "air_passengers = pd.read_csv('data/AirPassengers.csv')\n",
122 | "x = np.array(air_passengers['#Passengers'].values)\n",
123 | "n_predict = 300\n",
124 | "extrapolation = fourierExtrapolation(x, n_predict)\n",
125 | "plt.plot(np.arange(0, x.size), x, 'b', label = 'x', linewidth = 3)\n",
126 | "plt.plot(np.arange(0, extrapolation.size), extrapolation, 'r', label = 'extrapolation')\n",
127 | "plt.legend()"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": true
135 | },
136 | "outputs": [],
137 | "source": []
138 | }
139 | ],
140 | "metadata": {
141 | "anaconda-cloud": {},
142 | "kernelspec": {
143 | "display_name": "Python [Root]",
144 | "language": "python",
145 | "name": "Python [Root]"
146 | },
147 | "language_info": {
148 | "codemirror_mode": {
149 | "name": "ipython",
150 | "version": 3
151 | },
152 | "file_extension": ".py",
153 | "mimetype": "text/x-python",
154 | "name": "python",
155 | "nbconvert_exporter": "python",
156 | "pygments_lexer": "ipython3",
157 | "version": "3.5.2"
158 | },
159 | "widgets": {
160 | "state": {},
161 | "version": "1.1.1"
162 | }
163 | },
164 | "nbformat": 4,
165 | "nbformat_minor": 0
166 | }
167 |
--------------------------------------------------------------------------------
/10. Clustering & Classification.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "%matplotlib inline\n",
12 | "import matplotlib.pylab as plt\n",
13 | "\n",
14 | "from matplotlib.pylab import rcParams\n",
15 | "rcParams['figure.figsize'] = 15, 6\n",
16 | "\n",
17 | "from datetime import datetime\n",
18 | "from scipy.cluster.hierarchy import dendrogram, linkage\n",
19 | "import pandas as pd\n",
20 | "import numpy as np\n",
21 | "from sklearn.metrics.pairwise import pairwise_distances\n",
22 | "from math import sqrt\n",
23 | "from scipy.spatial.distance import squareform"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {
30 | "collapsed": false
31 | },
32 | "outputs": [],
33 | "source": [
34 | "words = pd.read_csv('data/50words_TEST.csv', index_col = 0, header = None)"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {
41 | "collapsed": false
42 | },
43 | "outputs": [],
44 | "source": [
45 | "words.index"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "### Let's take a look at some of the words 'on average'"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {
59 | "collapsed": false
60 | },
61 | "outputs": [],
62 | "source": [
63 | "for i in range(7):\n",
64 | " row = words.groupby(words.index).mean().iloc[i]\n",
65 | " row.plot()"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "### We can also check to see whether the 'average' matches the individual plot for a given type\n",
73 | "\n",
74 | "First, the 'average'"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": null,
80 | "metadata": {
81 | "collapsed": false
82 | },
83 | "outputs": [],
84 | "source": [
85 | "word_type = 7\n",
86 | "row = words.groupby(words.index).mean().iloc[word_type-1]\n",
87 | "row.plot()"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": null,
93 | "metadata": {
94 | "collapsed": false
95 | },
96 | "outputs": [],
97 | "source": [
98 | "word_type = 7\n",
99 | "row = words.groupby(words.index).median().iloc[word_type-1]\n",
100 | "row.plot()"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "Next the full sample of all those words"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "metadata": {
114 | "collapsed": false
115 | },
116 | "outputs": [],
117 | "source": [
118 | "for i in range(words[words.index == word_type].shape[0]):\n",
119 | " row = words[words.index == word_type].iloc[i]\n",
120 | " row.plot()"
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {},
126 | "source": [
127 | "### Let's try to code up the sensible distance function to describe the distance between two times series"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": true
135 | },
136 | "outputs": [],
137 | "source": [
138 | "# courtesy of http://alexminnaar.com/time-series-classification-and-clustering-with-python.html\n",
139 | "# %load snippets/dtwdistance.py"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": null,
145 | "metadata": {
146 | "collapsed": false
147 | },
148 | "outputs": [],
149 | "source": [
150 | "chosen_words = words[words.index == word_type]\n",
151 | "s1 = chosen_words.iloc[2]\n",
152 | "s2 = chosen_words.iloc[3]\n",
153 | "print(type(s1))\n",
154 | "DTWDistance(s1.values, s2.values)"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": null,
160 | "metadata": {
161 | "collapsed": false
162 | },
163 | "outputs": [],
164 | "source": [
165 | "s3 = words.iloc[0]\n",
166 | "DTWDistance(s1.values, s3.values)"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {
173 | "collapsed": false
174 | },
175 | "outputs": [],
176 | "source": [
177 | "s3 = words.iloc[0]\n",
178 | "DTWDistance(s2.values, s3.values)"
179 | ]
180 | },
181 | {
182 | "cell_type": "code",
183 | "execution_count": null,
184 | "metadata": {
185 | "collapsed": false
186 | },
187 | "outputs": [],
188 | "source": [
189 | "plt.plot(s1)\n",
190 | "plt.plot(s2)\n",
191 | "plt.plot(s3)"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "### Compare the performance of Euclidean distance with that of DTDW for s1, s2, s3 as specified above"
199 | ]
200 | },
201 | {
202 | "cell_type": "code",
203 | "execution_count": null,
204 | "metadata": {
205 | "collapsed": true
206 | },
207 | "outputs": [],
208 | "source": [
209 | "# %load snippets/euclidedistance.py"
210 | ]
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": null,
215 | "metadata": {
216 | "collapsed": false
217 | },
218 | "outputs": [],
219 | "source": [
220 | "EuclidDistance(s1.values, s2.values)"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": null,
226 | "metadata": {
227 | "collapsed": false
228 | },
229 | "outputs": [],
230 | "source": [
231 | "EuclidDistance(s3.values, s2.values)"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {
238 | "collapsed": false
239 | },
240 | "outputs": [],
241 | "source": [
242 | "EuclidDistance(s1.values, s3.values)"
243 | ]
244 | },
245 | {
246 | "cell_type": "markdown",
247 | "metadata": {},
248 | "source": [
249 | "### Can you classify a random row by determining which 'mean' curve it is closest to? How successful is this?"
250 | ]
251 | },
252 | {
253 | "cell_type": "code",
254 | "execution_count": null,
255 | "metadata": {
256 | "collapsed": false
257 | },
258 | "outputs": [],
259 | "source": [
260 | "mean_curve = {}\n",
261 | "for j in range(1,len(set(words.index))):\n",
262 | " row = words[words.index == j].mean()\n",
263 | " mean_curve[j] = row"
264 | ]
265 | },
266 | {
267 | "cell_type": "code",
268 | "execution_count": null,
269 | "metadata": {
270 | "collapsed": false
271 | },
272 | "outputs": [],
273 | "source": [
274 | "test_word = words[words.index == 5].iloc[3]"
275 | ]
276 | },
277 | {
278 | "cell_type": "code",
279 | "execution_count": null,
280 | "metadata": {
281 | "collapsed": false
282 | },
283 | "outputs": [],
284 | "source": [
285 | "distance_dict = {key:DTWDistance(test_word.values, value.values) for (key, value) in mean_curve.items() }\n"
286 | ]
287 | },
288 | {
289 | "cell_type": "code",
290 | "execution_count": null,
291 | "metadata": {
292 | "collapsed": false
293 | },
294 | "outputs": [],
295 | "source": [
296 | "from collections import OrderedDict\n",
297 | "\n",
298 | "OrderedDict(sorted(distance_dict.items(), key=lambda t: t[1]))"
299 | ]
300 | },
301 | {
302 | "cell_type": "markdown",
303 | "metadata": {},
304 | "source": [
305 | "### Can you cluster the words using the DTW metric?"
306 | ]
307 | },
308 | {
309 | "cell_type": "code",
310 | "execution_count": null,
311 | "metadata": {
312 | "collapsed": true
313 | },
314 | "outputs": [],
315 | "source": [
316 | "# Yes, but this would take a really long time, so we're not going to do it"
317 | ]
318 | },
319 | {
320 | "cell_type": "markdown",
321 | "metadata": {},
322 | "source": [
323 | "### Instead cluster with features"
324 | ]
325 | },
326 | {
327 | "cell_type": "code",
328 | "execution_count": null,
329 | "metadata": {
330 | "collapsed": false
331 | },
332 | "outputs": [],
333 | "source": [
334 | "max_location = []\n",
335 | "first_local_max_location = []\n",
336 | "second_local_max_location = []\n",
337 | "num_inflections = []\n",
338 | "ratio_first_local_max_to_abs_max = []\n",
339 | "word_type = []\n",
340 | "\n",
341 | "def smooth(y, box_pts):\n",
342 | " box = np.ones(box_pts)/box_pts\n",
343 | " y_smooth = np.convolve(y, box, mode='same')\n",
344 | " return y_smooth\n",
345 | "\n",
346 | "for row in range(words.shape[1]):\n",
347 | " word_type.append(words.index[row])\n",
348 | " \n",
349 | " # locations of maximum, locations of first and second inflection points, number of inflection points\n",
350 | " w = words.iloc[row]\n",
351 | " \n",
352 | " # max point\n",
353 | " max_location.append(w.idxmax())\n",
354 | " \n",
355 | " # local maxima and minima\n",
356 | " w_arr = np.array(w)\n",
357 | " w_arr = smooth(w_arr, 10)\n",
358 | " \n",
359 | " lows = np.where(np.r_[True, w_arr[1:] < w_arr[:-1]] & np.r_[w_arr[:-1] < w_arr[1:], True])\n",
360 | " lows = lows[0]\n",
361 | " mask = ((265 > lows ) & (lows > 5))\n",
362 | " lows = lows[mask]\n",
363 | " \n",
364 | " highs = np.where(np.r_[True, w_arr[1:] > w_arr[:-1]] & np.r_[w_arr[:-1] > w_arr[1:], True])\n",
365 | " highs = highs[0]\n",
366 | " mask = ((265 > highs) & (highs > 5))\n",
367 | " highs = highs[mask]\n",
368 | " \n",
369 | " first_local_max_location.append(highs[0])\n",
370 | " second_local_max_location.append(highs[1])\n",
371 | "\n",
372 | " ratio_first_local_max_to_abs_max.append(w_arr[highs[0]]/w_arr[w.idxmax()])\n",
373 | " \n",
374 | " num_inflections.append(len(highs) + len(lows))"
375 | ]
376 | },
377 | {
378 | "cell_type": "code",
379 | "execution_count": null,
380 | "metadata": {
381 | "collapsed": true
382 | },
383 | "outputs": [],
384 | "source": [
385 | "results = pd.DataFrame({'word_type' : word_type,\n",
386 | " 'max_location': max_location, \n",
387 | " 'first_local_max_location' : first_local_max_location,\n",
388 | " 'second_local_max_location' : second_local_max_location,\n",
389 | " 'num_inflections' : num_inflections,\n",
390 | " 'ratio_first_local_max_to_abs_max' : ratio_first_local_max_to_abs_max})"
391 | ]
392 | },
393 | {
394 | "cell_type": "code",
395 | "execution_count": null,
396 | "metadata": {
397 | "collapsed": false
398 | },
399 | "outputs": [],
400 | "source": [
401 | "results.head()"
402 | ]
403 | },
404 | {
405 | "cell_type": "code",
406 | "execution_count": null,
407 | "metadata": {
408 | "collapsed": true
409 | },
410 | "outputs": [],
411 | "source": [
412 | "from sklearn.cluster import KMeans"
413 | ]
414 | },
415 | {
416 | "cell_type": "code",
417 | "execution_count": null,
418 | "metadata": {
419 | "collapsed": false
420 | },
421 | "outputs": [],
422 | "source": [
423 | "estimator = KMeans(n_clusters=50)\n",
424 | "estimator.fit(results.drop('word_type', axis=1))"
425 | ]
426 | },
427 | {
428 | "cell_type": "code",
429 | "execution_count": null,
430 | "metadata": {
431 | "collapsed": false
432 | },
433 | "outputs": [],
434 | "source": [
435 | "results['labels'] = estimator.labels_"
436 | ]
437 | },
438 | {
439 | "cell_type": "code",
440 | "execution_count": null,
441 | "metadata": {
442 | "collapsed": false
443 | },
444 | "outputs": [],
445 | "source": [
446 | "results[results.word_type == 5]"
447 | ]
448 | },
449 | {
450 | "cell_type": "code",
451 | "execution_count": null,
452 | "metadata": {
453 | "collapsed": true
454 | },
455 | "outputs": [],
456 | "source": []
457 | }
458 | ],
459 | "metadata": {
460 | "anaconda-cloud": {},
461 | "kernelspec": {
462 | "display_name": "Python [Root]",
463 | "language": "python",
464 | "name": "Python [Root]"
465 | },
466 | "language_info": {
467 | "codemirror_mode": {
468 | "name": "ipython",
469 | "version": 3
470 | },
471 | "file_extension": ".py",
472 | "mimetype": "text/x-python",
473 | "name": "python",
474 | "nbconvert_exporter": "python",
475 | "pygments_lexer": "ipython3",
476 | "version": "3.5.2"
477 | },
478 | "widgets": {
479 | "state": {},
480 | "version": "1.1.1"
481 | }
482 | },
483 | "nbformat": 4,
484 | "nbformat_minor": 0
485 | }
486 |
--------------------------------------------------------------------------------
/data/AirPassengers.csv:
--------------------------------------------------------------------------------
1 | Month,#Passengers
1949-01,112
1949-02,118
1949-03,132
1949-04,129
1949-05,121
1949-06,135
1949-07,148
1949-08,148
1949-09,136
1949-10,119
1949-11,104
1949-12,118
1950-01,115
1950-02,126
1950-03,141
1950-04,135
1950-05,125
1950-06,149
1950-07,170
1950-08,170
1950-09,158
1950-10,133
1950-11,114
1950-12,140
1951-01,145
1951-02,150
1951-03,178
1951-04,163
1951-05,172
1951-06,178
1951-07,199
1951-08,199
1951-09,184
1951-10,162
1951-11,146
1951-12,166
1952-01,171
1952-02,180
1952-03,193
1952-04,181
1952-05,183
1952-06,218
1952-07,230
1952-08,242
1952-09,209
1952-10,191
1952-11,172
1952-12,194
1953-01,196
1953-02,196
1953-03,236
1953-04,235
1953-05,229
1953-06,243
1953-07,264
1953-08,272
1953-09,237
1953-10,211
1953-11,180
1953-12,201
1954-01,204
1954-02,188
1954-03,235
1954-04,227
1954-05,234
1954-06,264
1954-07,302
1954-08,293
1954-09,259
1954-10,229
1954-11,203
1954-12,229
1955-01,242
1955-02,233
1955-03,267
1955-04,269
1955-05,270
1955-06,315
1955-07,364
1955-08,347
1955-09,312
1955-10,274
1955-11,237
1955-12,278
1956-01,284
1956-02,277
1956-03,317
1956-04,313
1956-05,318
1956-06,374
1956-07,413
1956-08,405
1956-09,355
1956-10,306
1956-11,271
1956-12,306
1957-01,315
1957-02,301
1957-03,356
1957-04,348
1957-05,355
1957-06,422
1957-07,465
1957-08,467
1957-09,404
1957-10,347
1957-11,305
1957-12,336
1958-01,340
1958-02,318
1958-03,362
1958-04,348
1958-05,363
1958-06,435
1958-07,491
1958-08,505
1958-09,404
1958-10,359
1958-11,310
1958-12,337
1959-01,360
1959-02,342
1959-03,406
1959-04,396
1959-05,420
1959-06,472
1959-07,548
1959-08,559
1959-09,463
1959-10,407
1959-11,362
1959-12,405
1960-01,417
1960-02,391
1960-03,419
1960-04,461
1960-05,472
1960-06,535
1960-07,622
1960-08,606
1960-09,508
1960-10,461
1960-11,390
1960-12,432
--------------------------------------------------------------------------------
/data/ao_monthly.txt:
--------------------------------------------------------------------------------
1 | 1950 1 -0.60310E-01
2 | 1950 2 0.62681E+00
3 | 1950 3 -0.81275E-02
4 | 1950 4 0.55510E+00
5 | 1950 5 0.71577E-01
6 | 1950 6 0.53857E+00
7 | 1950 7 -0.80248E+00
8 | 1950 8 -0.85101E+00
9 | 1950 9 0.35797E+00
10 | 1950 10 -0.37890E+00
11 | 1950 11 -0.51511E+00
12 | 1950 12 -0.19281E+01
13 | 1951 1 -0.84969E-01
14 | 1951 2 -0.39993E+00
15 | 1951 3 -0.19341E+01
16 | 1951 4 -0.77648E+00
17 | 1951 5 -0.86278E+00
18 | 1951 6 -0.91786E+00
19 | 1951 7 0.90023E-01
20 | 1951 8 -0.37741E+00
21 | 1951 9 -0.81778E+00
22 | 1951 10 -0.21291E+00
23 | 1951 11 -0.68519E-01
24 | 1951 12 0.19872E+01
25 | 1952 1 0.36825E+00
26 | 1952 2 -0.17472E+01
27 | 1952 3 -0.18595E+01
28 | 1952 4 0.53852E+00
29 | 1952 5 -0.77351E+00
30 | 1952 6 -0.44093E+00
31 | 1952 7 0.38308E+00
32 | 1952 8 -0.30367E-01
33 | 1952 9 -0.38345E+00
34 | 1952 10 -0.43717E+00
35 | 1952 11 -0.18909E+01
36 | 1952 12 -0.18267E+01
37 | 1953 1 -0.10362E+01
38 | 1953 2 -0.24930E+00
39 | 1953 3 0.10683E+01
40 | 1953 4 -0.12558E+01
41 | 1953 5 -0.56207E+00
42 | 1953 6 0.22535E-01
43 | 1953 7 0.33317E+00
44 | 1953 8 0.84960E-01
45 | 1953 9 0.66161E+00
46 | 1953 10 -0.19446E+00
47 | 1953 11 0.35360E+00
48 | 1953 12 0.57547E+00
49 | 1954 1 -0.14829E+00
50 | 1954 2 -0.18094E+00
51 | 1954 3 0.47572E+00
52 | 1954 4 0.51169E+00
53 | 1954 5 -0.16561E+01
54 | 1954 6 -0.26811E+00
55 | 1954 7 0.34089E+00
56 | 1954 8 -0.12241E+00
57 | 1954 9 0.30150E+00
58 | 1954 10 0.51257E+00
59 | 1954 11 -0.32835E+00
60 | 1954 12 0.55259E+00
61 | 1955 1 -0.11631E+01
62 | 1955 2 -0.15423E+01
63 | 1955 3 -0.15681E+01
64 | 1955 4 0.19423E+00
65 | 1955 5 0.24161E+00
66 | 1955 6 -0.26578E+00
67 | 1955 7 0.33194E+00
68 | 1955 8 0.76012E+00
69 | 1955 9 0.35676E+00
70 | 1955 10 0.99053E-01
71 | 1955 11 -0.13422E+01
72 | 1955 12 -0.44403E+00
73 | 1956 1 -0.12044E+01
74 | 1956 2 -0.20286E+01
75 | 1956 3 0.47036E+00
76 | 1956 4 -0.86753E+00
77 | 1956 5 0.13911E+01
78 | 1956 6 0.28014E+00
79 | 1956 7 -0.21460E+00
80 | 1956 8 -0.65221E+00
81 | 1956 9 -0.20195E+00
82 | 1956 10 0.11392E+01
83 | 1956 11 -0.66280E-01
84 | 1956 12 0.89139E-03
85 | 1957 1 0.20621E+01
86 | 1957 2 -0.15132E+01
87 | 1957 3 -0.20126E+01
88 | 1957 4 0.23766E+00
89 | 1957 5 -0.96610E+00
90 | 1957 6 -0.75999E+00
91 | 1957 7 -0.64620E+00
92 | 1957 8 0.96898E-01
93 | 1957 9 -0.95588E+00
94 | 1957 10 0.90314E+00
95 | 1957 11 -0.13800E+01
96 | 1957 12 0.82801E+00
97 | 1958 1 -0.14382E+01
98 | 1958 2 -0.22282E+01
99 | 1958 3 -0.25218E+01
100 | 1958 4 -0.36002E+00
101 | 1958 5 -0.33635E+00
102 | 1958 6 -0.11493E+01
103 | 1958 7 -0.68374E+00
104 | 1958 8 -0.75479E+00
105 | 1958 9 -0.12058E-01
106 | 1958 10 0.77009E+00
107 | 1958 11 -0.10675E-01
108 | 1958 12 -0.16865E+01
109 | 1959 1 -0.20128E+01
110 | 1959 2 0.25445E+01
111 | 1959 3 0.14318E+01
112 | 1959 4 0.11924E+00
113 | 1959 5 -0.34076E+00
114 | 1959 6 -0.33434E-01
115 | 1959 7 0.10472E+00
116 | 1959 8 -0.74521E+00
117 | 1959 9 -0.28076E+00
118 | 1959 10 -0.24905E+00
119 | 1959 11 -0.14106E+01
120 | 1959 12 -0.41950E-01
121 | 1960 1 -0.24842E+01
122 | 1960 2 -0.22124E+01
123 | 1960 3 -0.16246E+01
124 | 1960 4 -0.29731E+00
125 | 1960 5 -0.85743E+00
126 | 1960 6 0.54978E-01
127 | 1960 7 -0.61906E+00
128 | 1960 8 -0.10079E+01
129 | 1960 9 -0.38164E+00
130 | 1960 10 -0.11870E+01
131 | 1960 11 -0.55323E+00
132 | 1960 12 -0.34295E+00
133 | 1961 1 -0.15060E+01
134 | 1961 2 0.62115E+00
135 | 1961 3 0.34144E+00
136 | 1961 4 -0.23749E+00
137 | 1961 5 0.15748E+00
138 | 1961 6 0.83696E+00
139 | 1961 7 -0.10797E+00
140 | 1961 8 0.12693E-01
141 | 1961 9 0.81485E+00
142 | 1961 10 0.20308E+00
143 | 1961 11 -0.10438E-01
144 | 1961 12 -0.16682E+01
145 | 1962 1 0.16445E+01
146 | 1962 2 -0.35815E+00
147 | 1962 3 -0.28480E+01
148 | 1962 4 0.11692E+01
149 | 1962 5 0.67997E-01
150 | 1962 6 0.28707E+00
151 | 1962 7 -0.92651E+00
152 | 1962 8 0.15207E+00
153 | 1962 9 -0.55986E-01
154 | 1962 10 -0.15827E-01
155 | 1962 11 -0.11123E+01
156 | 1962 12 -0.71143E+00
157 | 1963 1 -0.33112E+01
158 | 1963 2 -0.17208E+01
159 | 1963 3 0.72422E+00
160 | 1963 4 -0.34769E+00
161 | 1963 5 0.77098E+00
162 | 1963 6 -0.58500E+00
163 | 1963 7 -0.30347E+00
164 | 1963 8 -0.62474E+00
165 | 1963 9 0.83110E-01
166 | 1963 10 0.10692E+01
167 | 1963 11 -0.41944E+00
168 | 1963 12 -0.11781E+01
169 | 1964 1 0.38463E+00
170 | 1964 2 -0.57491E+00
171 | 1964 3 -0.55817E+00
172 | 1964 4 0.66339E+00
173 | 1964 5 0.11740E+01
174 | 1964 6 0.14159E+00
175 | 1964 7 0.73418E+00
176 | 1964 8 -0.12066E+01
177 | 1964 9 -0.22718E+00
178 | 1964 10 0.34171E+00
179 | 1964 11 -0.34440E+00
180 | 1964 12 -0.24609E+00
181 | 1965 1 -0.10458E+01
182 | 1965 2 -0.20841E+01
183 | 1965 3 -0.90496E+00
184 | 1965 4 0.56812E+00
185 | 1965 5 -0.15253E+00
186 | 1965 6 0.37800E-01
187 | 1965 7 -0.50987E+00
188 | 1965 8 -0.25487E+00
189 | 1965 9 -0.69781E+00
190 | 1965 10 0.39367E+00
191 | 1965 11 -0.13412E+01
192 | 1965 12 0.16297E+00
193 | 1966 1 -0.32320E+01
194 | 1966 2 -0.14381E+01
195 | 1966 3 -0.91066E+00
196 | 1966 4 -0.18373E+01
197 | 1966 5 0.11243E+01
198 | 1966 6 0.40797E+00
199 | 1966 7 0.10944E-01
200 | 1966 8 -0.94527E+00
201 | 1966 9 0.11063E-01
202 | 1966 10 -0.10766E+01
203 | 1966 11 0.11056E+00
204 | 1966 12 -0.14015E+01
205 | 1967 1 -0.57592E+00
206 | 1967 2 0.11801E+01
207 | 1967 3 0.19668E+01
208 | 1967 4 0.16996E+01
209 | 1967 5 0.12651E+00
210 | 1967 6 0.64659E+00
211 | 1967 7 0.25926E+00
212 | 1967 8 -0.29302E+00
213 | 1967 9 0.13293E+00
214 | 1967 10 0.12986E+01
215 | 1967 11 0.33356E+00
216 | 1967 12 -0.34693E+00
217 | 1968 1 -0.40879E+00
218 | 1968 2 -0.21537E+01
219 | 1968 3 0.17408E+01
220 | 1968 4 0.32768E+00
221 | 1968 5 -0.24062E+00
222 | 1968 6 0.41966E+00
223 | 1968 7 -0.83611E+00
224 | 1968 8 -0.67063E+00
225 | 1968 9 -0.10089E+01
226 | 1968 10 -0.10132E+01
227 | 1968 11 -0.21826E+01
228 | 1968 12 -0.78317E+00
229 | 1969 1 -0.29675E+01
230 | 1969 2 -0.31135E+01
231 | 1969 3 -0.15822E+01
232 | 1969 4 0.43846E+00
233 | 1969 5 -0.72032E+00
234 | 1969 6 -0.34780E+00
235 | 1969 7 0.40951E+00
236 | 1969 8 -0.78176E+00
237 | 1969 9 -0.83420E-01
238 | 1969 10 0.97581E-01
239 | 1969 11 0.32577E+00
240 | 1969 12 -0.18556E+01
241 | 1970 1 -0.24124E+01
242 | 1970 2 -0.13253E+01
243 | 1970 3 -0.20841E+01
244 | 1970 4 0.30205E+00
245 | 1970 5 0.53057E+00
246 | 1970 6 0.87539E+00
247 | 1970 7 0.13865E+00
248 | 1970 8 -0.26255E+00
249 | 1970 9 0.29661E-01
250 | 1970 10 0.98180E-01
251 | 1970 11 0.37838E+00
252 | 1970 12 -0.39915E+00
253 | 1971 1 -0.16273E+00
254 | 1971 2 -0.92190E+00
255 | 1971 3 -0.10907E+01
256 | 1971 4 -0.58343E+00
257 | 1971 5 0.67926E+00
258 | 1971 6 -0.66827E+00
259 | 1971 7 -0.57847E+00
260 | 1971 8 0.81753E+00
261 | 1971 9 0.15341E+00
262 | 1971 10 0.11847E+01
263 | 1971 11 0.41883E+00
264 | 1971 12 0.82387E+00
265 | 1972 1 0.16650E+00
266 | 1972 2 -0.19542E+00
267 | 1972 3 -0.14068E+00
268 | 1972 4 0.10074E+01
269 | 1972 5 0.14023E+00
270 | 1972 6 -0.49071E-01
271 | 1972 7 -0.55291E+00
272 | 1972 8 -0.82042E-01
273 | 1972 9 -0.91956E+00
274 | 1972 10 0.39177E+00
275 | 1972 11 -0.38032E+00
276 | 1972 12 0.12375E+01
277 | 1973 1 0.12318E+01
278 | 1973 2 0.78621E+00
279 | 1973 3 0.53717E+00
280 | 1973 4 -0.11257E+01
281 | 1973 5 0.73456E-01
282 | 1973 6 0.53116E+00
283 | 1973 7 0.27047E+00
284 | 1973 8 0.31251E+00
285 | 1973 9 0.11416E+00
286 | 1973 10 0.33710E+00
287 | 1973 11 0.22447E-02
288 | 1973 12 -0.18148E+00
289 | 1974 1 0.23216E+00
290 | 1974 2 -0.48927E+00
291 | 1974 3 -0.74628E+00
292 | 1974 4 0.30882E+00
293 | 1974 5 -0.50704E+00
294 | 1974 6 -0.47510E-01
295 | 1974 7 0.38996E+00
296 | 1974 8 -0.53337E+00
297 | 1974 9 -0.13579E+00
298 | 1974 10 -0.10239E+01
299 | 1974 11 -0.43475E+00
300 | 1974 12 0.55645E+00
301 | 1975 1 0.15945E+01
302 | 1975 2 0.19446E+00
303 | 1975 3 0.15120E+00
304 | 1975 4 0.40878E+00
305 | 1975 5 -0.61433E+00
306 | 1975 6 -0.32323E+00
307 | 1975 7 0.34529E+00
308 | 1975 8 0.13004E+00
309 | 1975 9 0.12783E+01
310 | 1975 10 0.13771E+00
311 | 1975 11 0.61870E+00
312 | 1975 12 0.12898E+01
313 | 1976 1 0.34333E-01
314 | 1976 2 0.16563E+01
315 | 1976 3 0.58709E+00
316 | 1976 4 0.43968E+00
317 | 1976 5 0.59626E-01
318 | 1976 6 0.32800E+00
319 | 1976 7 -0.32529E+00
320 | 1976 8 0.55859E+00
321 | 1976 9 -0.74252E+00
322 | 1976 10 -0.80412E+00
323 | 1976 11 -0.87349E-01
324 | 1976 12 -0.20743E+01
325 | 1977 1 -0.37671E+01
326 | 1977 2 -0.20105E+01
327 | 1977 3 0.34446E+00
328 | 1977 4 0.13285E+01
329 | 1977 5 0.10432E+00
330 | 1977 6 -0.22616E+00
331 | 1977 7 -0.49173E+00
332 | 1977 8 -0.14122E+01
333 | 1977 9 0.58648E+00
334 | 1977 10 -0.91780E-02
335 | 1977 11 0.60528E+00
336 | 1977 12 -0.23965E+00
337 | 1978 1 -0.34696E+00
338 | 1978 2 -0.30136E+01
339 | 1978 3 0.50191E+00
340 | 1978 4 -0.96708E+00
341 | 1978 5 0.59049E-01
342 | 1978 6 0.63464E+00
343 | 1978 7 -0.60399E+00
344 | 1978 8 -0.35366E+00
345 | 1978 9 -0.98999E-01
346 | 1978 10 0.89460E+00
347 | 1978 11 0.24695E+01
348 | 1978 12 -0.98014E+00
349 | 1979 1 -0.22328E+01
350 | 1979 2 -0.69671E+00
351 | 1979 3 -0.81414E+00
352 | 1979 4 -0.11568E+01
353 | 1979 5 -0.25009E+00
354 | 1979 6 0.93316E+00
355 | 1979 7 0.38511E-01
356 | 1979 8 -0.68413E+00
357 | 1979 9 -0.45949E-01
358 | 1979 10 -0.12434E+01
359 | 1979 11 0.47508E+00
360 | 1979 12 0.12948E+01
361 | 1980 1 -0.20657E+01
362 | 1980 2 -0.93372E+00
363 | 1980 3 -0.14333E+01
364 | 1980 4 -0.41913E+00
365 | 1980 5 -0.11548E+01
366 | 1980 6 0.72149E+00
367 | 1980 7 -0.62221E+00
368 | 1980 8 -0.18519E+00
369 | 1980 9 0.31262E+00
370 | 1980 10 -0.52121E+00
371 | 1980 11 -0.13610E+01
372 | 1980 12 -0.57300E-01
373 | 1981 1 -0.11634E+00
374 | 1981 2 -0.33158E+00
375 | 1981 3 -0.16447E+01
376 | 1981 4 0.43041E+00
377 | 1981 5 0.17956E+00
378 | 1981 6 -0.43793E+00
379 | 1981 7 0.56055E+00
380 | 1981 8 -0.24411E+00
381 | 1981 9 -0.10401E+01
382 | 1981 10 -0.11675E+01
383 | 1981 11 -0.18767E+00
384 | 1981 12 -0.12157E+01
385 | 1982 1 -0.88341E+00
386 | 1982 2 0.97391E+00
387 | 1982 3 0.10741E+01
388 | 1982 4 0.14538E+01
389 | 1982 5 -0.20870E+00
390 | 1982 6 -0.11801E+01
391 | 1982 7 0.47753E-02
392 | 1982 8 0.36223E+00
393 | 1982 9 0.55772E+00
394 | 1982 10 -0.21098E+00
395 | 1982 11 0.66093E+00
396 | 1982 12 0.96718E+00
397 | 1983 1 0.13591E+01
398 | 1983 2 -0.18059E+01
399 | 1983 3 -0.56707E+00
400 | 1983 4 -0.73776E+00
401 | 1983 5 -0.44093E+00
402 | 1983 6 0.31253E+00
403 | 1983 7 0.13055E+00
404 | 1983 8 0.10978E+01
405 | 1983 9 0.16689E+00
406 | 1983 10 0.13689E+01
407 | 1983 11 -0.68793E+00
408 | 1983 12 0.18625E+00
409 | 1984 1 0.90504E+00
410 | 1984 2 -0.30272E+00
411 | 1984 3 -0.23860E+01
412 | 1984 4 -0.28359E+00
413 | 1984 5 0.47918E+00
414 | 1984 6 0.72895E-02
415 | 1984 7 0.18871E-01
416 | 1984 8 0.46569E+00
417 | 1984 9 -0.41276E+00
418 | 1984 10 -0.27026E+00
419 | 1984 11 -0.96587E+00
420 | 1984 12 0.44600E+00
421 | 1985 1 -0.28057E+01
422 | 1985 2 -0.14398E+01
423 | 1985 3 0.55144E+00
424 | 1985 4 0.65242E+00
425 | 1985 5 -0.43221E+00
426 | 1985 6 -0.34656E+00
427 | 1985 7 -0.38958E+00
428 | 1985 8 -0.14289E-02
429 | 1985 9 0.11441E+00
430 | 1985 10 0.10351E+01
431 | 1985 11 -0.12175E+01
432 | 1985 12 -0.19476E+01
433 | 1986 1 -0.56764E+00
434 | 1986 2 -0.29041E+01
435 | 1986 3 0.19308E+01
436 | 1986 4 0.10299E+00
437 | 1986 5 0.36687E+00
438 | 1986 6 0.53457E+00
439 | 1986 7 -0.82585E-02
440 | 1986 8 -0.82629E+00
441 | 1986 9 -0.23385E-01
442 | 1986 10 0.14246E+01
443 | 1986 11 0.92572E+00
444 | 1986 12 0.59768E-01
445 | 1987 1 -0.11476E+01
446 | 1987 2 -0.14732E+01
447 | 1987 3 -0.17465E+01
448 | 1987 4 0.38697E+00
449 | 1987 5 0.32524E+00
450 | 1987 6 -0.71027E+00
451 | 1987 7 -0.46627E+00
452 | 1987 8 -0.83570E+00
453 | 1987 9 0.28653E+00
454 | 1987 10 -0.80009E-01
455 | 1987 11 -0.53584E+00
456 | 1987 12 -0.53391E+00
457 | 1988 1 0.26466E+00
458 | 1988 2 -0.10662E+01
459 | 1988 3 -0.19707E+00
460 | 1988 4 -0.56071E+00
461 | 1988 5 -0.84614E+00
462 | 1988 6 0.60528E-01
463 | 1988 7 -0.14337E+00
464 | 1988 8 0.25457E+00
465 | 1988 9 0.10393E+01
466 | 1988 10 0.32359E-01
467 | 1988 11 -0.34655E-01
468 | 1988 12 0.16788E+01
469 | 1989 1 0.31060E+01
470 | 1989 2 0.32793E+01
471 | 1989 3 0.15303E+01
472 | 1989 4 -0.25024E+00
473 | 1989 5 0.88883E+00
474 | 1989 6 0.34498E+00
475 | 1989 7 0.86555E+00
476 | 1989 8 0.55090E+00
477 | 1989 9 0.70313E+00
478 | 1989 10 0.99069E+00
479 | 1989 11 0.33782E-01
480 | 1989 12 -0.64365E+00
481 | 1990 1 0.10007E+01
482 | 1990 2 0.34016E+01
483 | 1990 3 0.29900E+01
484 | 1990 4 0.18788E+01
485 | 1990 5 0.94282E+00
486 | 1990 6 0.30430E+00
487 | 1990 7 -0.29581E+00
488 | 1990 8 -0.18024E+00
489 | 1990 9 -0.21040E+00
490 | 1990 10 0.66034E+00
491 | 1990 11 0.52064E+00
492 | 1990 12 0.12767E+01
493 | 1991 1 0.72323E+00
494 | 1991 2 -0.87599E+00
495 | 1991 3 -0.52680E+00
496 | 1991 4 0.53021E+00
497 | 1991 5 0.48649E+00
498 | 1991 6 -0.11536E+00
499 | 1991 7 -0.18797E+00
500 | 1991 8 0.79688E+00
501 | 1991 9 -0.11221E+00
502 | 1991 10 -0.25195E+00
503 | 1991 11 0.28465E+00
504 | 1991 12 0.16132E+01
505 | 1992 1 0.55003E+00
506 | 1992 2 0.11217E+01
507 | 1992 3 0.98423E+00
508 | 1992 4 -0.52053E+00
509 | 1992 5 0.13414E+01
510 | 1992 6 -0.30196E+00
511 | 1992 7 0.19113E+00
512 | 1992 8 0.53534E+00
513 | 1992 9 -0.64030E+00
514 | 1992 10 -0.36589E+00
515 | 1992 11 0.71699E+00
516 | 1992 12 0.16267E+01
517 | 1993 1 0.34953E+01
518 | 1993 2 0.18450E+00
519 | 1993 3 0.76435E+00
520 | 1993 4 -0.43545E+00
521 | 1993 5 -0.16075E+01
522 | 1993 6 -0.51951E+00
523 | 1993 7 -0.51070E+00
524 | 1993 8 -0.39299E+00
525 | 1993 9 -0.36063E+00
526 | 1993 10 -0.56501E+00
527 | 1993 11 0.10018E+01
528 | 1993 12 -0.10412E+00
529 | 1994 1 -0.28785E+00
530 | 1994 2 -0.86154E+00
531 | 1994 3 0.18810E+01
532 | 1994 4 0.22474E+00
533 | 1994 5 -0.11545E+00
534 | 1994 6 0.16063E+01
535 | 1994 7 0.35074E+00
536 | 1994 8 0.82753E+00
537 | 1994 9 -0.84055E-01
538 | 1994 10 0.17403E+00
539 | 1994 11 0.17794E+01
540 | 1994 12 0.89383E+00
541 | 1995 1 -0.15377E+00
542 | 1995 2 0.14289E+01
543 | 1995 3 0.39323E+00
544 | 1995 4 -0.96313E+00
545 | 1995 5 -0.89120E+00
546 | 1995 6 -0.11182E+00
547 | 1995 7 -0.21708E+00
548 | 1995 8 0.54359E+00
549 | 1995 9 -0.54903E+00
550 | 1995 10 0.75041E-01
551 | 1995 11 -0.72327E+00
552 | 1995 12 -0.21271E+01
553 | 1996 1 -0.12004E+01
554 | 1996 2 0.16321E+00
555 | 1996 3 -0.14832E+01
556 | 1996 4 -0.15251E+01
557 | 1996 5 -0.22642E+00
558 | 1996 6 0.49673E+00
559 | 1996 7 0.71457E+00
560 | 1996 8 0.12471E+00
561 | 1996 9 -0.11400E+01
562 | 1996 10 0.18253E+00
563 | 1996 11 0.13637E+00
564 | 1996 12 -0.17208E+01
565 | 1997 1 -0.45677E+00
566 | 1997 2 0.18887E+01
567 | 1997 3 0.10908E+01
568 | 1997 4 0.32363E+00
569 | 1997 5 -0.96113E+00
570 | 1997 6 -0.81499E+00
571 | 1997 7 -0.43061E+00
572 | 1997 8 0.12062E+00
573 | 1997 9 0.19451E+00
574 | 1997 10 -0.69971E+00
575 | 1997 11 -0.66113E+00
576 | 1997 12 -0.71116E-01
577 | 1998 1 -0.20806E+01
578 | 1998 2 -0.18318E+00
579 | 1998 3 -0.25442E+00
580 | 1998 4 -0.37912E-01
581 | 1998 5 0.42864E+00
582 | 1998 6 -0.71073E+00
583 | 1998 7 -0.21167E+00
584 | 1998 8 0.65033E+00
585 | 1998 9 -0.10499E+01
586 | 1998 10 0.29433E+00
587 | 1998 11 -0.14494E+01
588 | 1998 12 0.13534E+01
589 | 1999 1 0.11035E+00
590 | 1999 2 0.48213E+00
591 | 1999 3 -0.14916E+01
592 | 1999 4 0.28445E+00
593 | 1999 5 0.22587E+00
594 | 1999 6 0.70703E+00
595 | 1999 7 -0.20418E-02
596 | 1999 8 -0.67215E+00
597 | 1999 9 0.59078E-01
598 | 1999 10 -0.58023E-02
599 | 1999 11 0.61094E+00
600 | 1999 12 0.10431E+01
601 | 2000 1 0.12702E+01
602 | 2000 2 0.10758E+01
603 | 2000 3 -0.45136E+00
604 | 2000 4 -0.27852E+00
605 | 2000 5 0.96909E+00
606 | 2000 6 0.58610E+00
607 | 2000 7 -0.64943E+00
608 | 2000 8 0.14389E+00
609 | 2000 9 0.39486E+00
610 | 2000 10 0.31678E+00
611 | 2000 11 -0.15815E+01
612 | 2000 12 -0.23544E+01
613 | 2001 1 -0.95883E+00
614 | 2001 2 -0.62241E+00
615 | 2001 3 -0.16865E+01
616 | 2001 4 0.90598E+00
617 | 2001 5 0.45196E+00
618 | 2001 6 -0.15338E-01
619 | 2001 7 -0.30988E-01
620 | 2001 8 0.52050E+00
621 | 2001 9 -0.70660E+00
622 | 2001 10 0.70747E+00
623 | 2001 11 0.81865E+00
624 | 2001 12 -0.13224E+01
625 | 2002 1 0.13813E+01
626 | 2002 2 0.13035E+01
627 | 2002 3 0.90200E+00
628 | 2002 4 0.74841E+00
629 | 2002 5 0.40136E+00
630 | 2002 6 0.57274E+00
631 | 2002 7 0.32764E+00
632 | 2002 8 -0.22853E+00
633 | 2002 9 -0.42744E-01
634 | 2002 10 -0.14885E+01
635 | 2002 11 -0.14251E+01
636 | 2002 12 -0.15921E+01
637 | 2003 1 -0.47167E+00
638 | 2003 2 0.12780E+00
639 | 2003 3 0.93297E+00
640 | 2003 4 -0.17811E+00
641 | 2003 5 0.10167E+01
642 | 2003 6 -0.10212E+00
643 | 2003 7 0.75316E-01
644 | 2003 8 -0.28037E+00
645 | 2003 9 0.46658E+00
646 | 2003 10 -0.66981E+00
647 | 2003 11 0.64242E+00
648 | 2003 12 0.26521E+00
649 | 2004 1 -0.16858E+01
650 | 2004 2 -0.15285E+01
651 | 2004 3 0.31806E+00
652 | 2004 4 -0.40938E+00
653 | 2004 5 -0.94252E-01
654 | 2004 6 -0.23587E+00
655 | 2004 7 -0.20054E+00
656 | 2004 8 -0.72019E+00
657 | 2004 9 0.85501E+00
658 | 2004 10 -0.51542E+00
659 | 2004 11 0.67827E+00
660 | 2004 12 0.12301E+01
661 | 2005 1 0.35617E+00
662 | 2005 2 -0.12706E+01
663 | 2005 3 -0.13479E+01
664 | 2005 4 -0.46214E-01
665 | 2005 5 -0.76336E+00
666 | 2005 6 -0.38324E+00
667 | 2005 7 -0.30247E-01
668 | 2005 8 0.26141E-01
669 | 2005 9 0.80239E+00
670 | 2005 10 0.29768E-01
671 | 2005 11 0.22769E+00
672 | 2005 12 -0.21039E+01
673 | 2006 1 -0.17047E+00
674 | 2006 2 -0.15577E+00
675 | 2006 3 -0.16038E+01
676 | 2006 4 0.13833E+00
677 | 2006 5 0.15581E+00
678 | 2006 6 0.10708E+01
679 | 2006 7 0.10270E+00
680 | 2006 8 -0.26525E+00
681 | 2006 9 0.60649E+00
682 | 2006 10 -0.10291E+01
683 | 2006 11 0.52131E+00
684 | 2006 12 0.22817E+01
685 | 2007 1 0.20338E+01
686 | 2007 2 -0.13069E+01
687 | 2007 3 0.11821E+01
688 | 2007 4 0.54427E+00
689 | 2007 5 0.89367E+00
690 | 2007 6 -0.55496E+00
691 | 2007 7 -0.39652E+00
692 | 2007 8 -0.33738E-01
693 | 2007 9 0.17892E+00
694 | 2007 10 0.38348E+00
695 | 2007 11 -0.51866E+00
696 | 2007 12 0.82113E+00
697 | 2008 1 0.81896E+00
698 | 2008 2 0.93807E+00
699 | 2008 3 0.58559E+00
700 | 2008 4 -0.45501E+00
701 | 2008 5 -0.12047E+01
702 | 2008 6 -0.89780E-01
703 | 2008 7 -0.47992E+00
704 | 2008 8 -0.80482E-01
705 | 2008 9 -0.32657E+00
706 | 2008 10 0.16758E+01
707 | 2008 11 0.92205E-01
708 | 2008 12 0.64778E+00
709 | 2009 1 0.79975E+00
710 | 2009 2 -0.67230E+00
711 | 2009 3 0.12134E+00
712 | 2009 4 0.97253E+00
713 | 2009 5 0.11937E+01
714 | 2009 6 -0.13507E+01
715 | 2009 7 -0.13559E+01
716 | 2009 8 -0.53666E-01
717 | 2009 9 0.87451E+00
718 | 2009 10 -0.15399E+01
719 | 2009 11 0.45885E+00
720 | 2009 12 -0.34128E+01
721 | 2010 1 -0.25868E+01
722 | 2010 2 -0.42657E+01
723 | 2010 3 -0.43208E+00
724 | 2010 4 -0.27450E+00
725 | 2010 5 -0.91864E+00
726 | 2010 6 -0.13004E-01
727 | 2010 7 0.43527E+00
728 | 2010 8 -0.11660E+00
729 | 2010 9 -0.86464E+00
730 | 2010 10 -0.46697E+00
731 | 2010 11 -0.37575E+00
732 | 2010 12 -0.26310E+01
733 | 2011 1 -0.16831E+01
734 | 2011 2 0.15754E+01
735 | 2011 3 0.14241E+01
736 | 2011 4 0.22748E+01
737 | 2011 5 -0.35093E-01
738 | 2011 6 -0.85775E+00
739 | 2011 7 -0.47162E+00
740 | 2011 8 -0.10626E+01
741 | 2011 9 0.66474E+00
742 | 2011 10 0.79975E+00
743 | 2011 11 0.14592E+01
744 | 2011 12 0.22208E+01
745 | 2012 1 -0.21966E+00
746 | 2012 2 -0.36335E-01
747 | 2012 3 0.10371E+01
748 | 2012 4 -0.34571E-01
749 | 2012 5 0.16841E+00
750 | 2012 6 -0.67241E+00
751 | 2012 7 0.16779E+00
752 | 2012 8 0.13999E-01
753 | 2012 9 0.77225E+00
754 | 2012 10 -0.15140E+01
755 | 2012 11 -0.11057E+00
756 | 2012 12 -0.17486E+01
757 | 2013 1 -0.60952E+00
758 | 2013 2 -0.10074E+01
759 | 2013 3 -0.31854E+01
760 | 2013 4 0.32221E+00
761 | 2013 5 0.49401E+00
762 | 2013 6 0.54865E+00
763 | 2013 7 -0.11112E-01
764 | 2013 8 0.15425E+00
765 | 2013 9 -0.46088E+00
766 | 2013 10 0.26276E+00
767 | 2013 11 0.20290E+01
768 | 2013 12 0.14749E+01
769 | 2014 1 -0.96876E+00
770 | 2014 2 0.43775E-01
771 | 2014 3 0.12058E+01
772 | 2014 4 0.97197E+00
773 | 2014 5 0.46421E+00
774 | 2014 6 -0.50745E+00
775 | 2014 7 -0.48894E+00
776 | 2014 8 -0.37154E+00
777 | 2014 9 0.10191E+00
778 | 2014 10 -0.11344E+01
779 | 2014 11 -0.53030E+00
780 | 2014 12 0.41292E+00
781 | 2015 1 0.10916E+01
782 | 2015 2 0.10426E+01
783 | 2015 3 0.18374E+01
784 | 2015 4 0.12157E+01
785 | 2015 5 0.76276E+00
786 | 2015 6 0.42704E+00
787 | 2015 7 -0.11079E+01
788 | 2015 8 -0.68902E+00
789 | 2015 9 -0.16451E+00
790 | 2015 10 -0.25006E+00
791 | 2015 11 0.19450E+01
792 | 2015 12 0.14441E+01
793 | 2016 1 -0.14487E+01
794 | 2016 2 -0.23521E-01
795 | 2016 3 0.28024E+00
796 | 2016 4 -0.10511E+01
797 | 2016 5 -0.35739E-01
798 | 2016 6 0.31288E+00
799 |
--------------------------------------------------------------------------------
/readtime.py:
--------------------------------------------------------------------------------
1 | data = pd.read_fwf('data/ao_monthly.txt', header = None, index_col = 0, parse_dates = [[0, 1]], infer_datetime_format = True)
--------------------------------------------------------------------------------
/snippets/6_acf_def.py:
--------------------------------------------------------------------------------
1 | """
2 | Autocorrelation, also known as serial correlation, is the correlation of a signal with itself at different points in time. Informally, it is the similarity between observations as a function of the time lag between them.
3 | """
4 |
5 | pd.Series(acf(air_passengers.Passengers, nlags = 36)).plot()
6 |
--------------------------------------------------------------------------------
/snippets/6_acf_over_time.py:
--------------------------------------------------------------------------------
1 | air_passengers.rolling(window = 20).apply(lambda x: acf(x, nlags = 10)[10]).plot()
2 |
--------------------------------------------------------------------------------
/snippets/6_ad_test_desc.py:
--------------------------------------------------------------------------------
1 | print("""
2 | The null hypothesis of the Augmented Dickey-Fuller is that there is a unit root, with the alternative that there is no unit root. If the pvalue is above a critical size, then we cannot reject that there is a unit root.
3 |
4 | Rejecting that there is a unit root -> time series is stationary.
5 | """)
6 |
--------------------------------------------------------------------------------
/snippets/6_multi_vs_add.pu:
--------------------------------------------------------------------------------
1 | """
2 | The additive model is most appropriate if the magnitude of the seasonal fluctuations or the variation around the trend-cycle does not vary with the level of the time series. When the variation in the seasonal pattern, or the variation around the trend-cycle, appears to be proportional to the level of the time series, then a multiplicative model is more appropriate. With economic time series, multiplicative models are common.
3 | """
--------------------------------------------------------------------------------
/snippets/6_multi_vs_add.py:
--------------------------------------------------------------------------------
1 | """
2 | The additive model is most appropriate if the magnitude of the seasonal fluctuations or the variation around the trend-cycle does not vary with the level of the time series. When the variation in the seasonal pattern, or the variation around the trend-cycle, appears to be proportional to the level of the time series, then a multiplicative model is more appropriate. With economic time series, multiplicative models are common.
3 | """
4 |
--------------------------------------------------------------------------------
/snippets/6_pd.py:
--------------------------------------------------------------------------------
1 | air_passengers = air_passengers.to_period()
2 |
--------------------------------------------------------------------------------
/snippets/6_var.py:
--------------------------------------------------------------------------------
1 | air_passengers.rolling(window = 20).var().plot()
2 |
--------------------------------------------------------------------------------
/snippets/7_diff2.py:
--------------------------------------------------------------------------------
1 | log_air_passengers_diff_2 = log_air_passengers_diff - log_air_passengers_diff.shift()
2 | fig, ax = plt.subplots()
3 | ax.set_color_cycle(['red', 'blue'])
4 | plt.plot(log_air_passengers_diff)
5 | plt.plot(log_air_passengers_diff_2)
6 | plt.legend(loc = 'best')
7 |
--------------------------------------------------------------------------------
/snippets/7ma.py:
--------------------------------------------------------------------------------
1 | def ma1(theta = .5, n = 100):
2 | time_series = []
3 | error = np.random.randn(n)
4 | for period in range(1,n):
5 | time_series.append(error[period] + theta*error[period-1])
6 | return pd.Series(time_series[1:], index = range(1,n-1))
7 |
--------------------------------------------------------------------------------
/snippets/ambig.py:
--------------------------------------------------------------------------------
1 | rng_hourly.tz_localize('US/Central', ambiguous = 'infer')
--------------------------------------------------------------------------------
/snippets/changerep.py:
--------------------------------------------------------------------------------
1 | data.to_period()
--------------------------------------------------------------------------------
/snippets/confirm.py:
--------------------------------------------------------------------------------
1 | rng_hourly.tz_localize('US/Central', ambiguous = 'infer').tz_convert('utc')
--------------------------------------------------------------------------------
/snippets/custom_rolling.py:
--------------------------------------------------------------------------------
1 | df.rolling(window = 10, center = False).apply(lambda x: x[1]/x[2])[1:10]
--------------------------------------------------------------------------------
/snippets/custom_rolling2.py:
--------------------------------------------------------------------------------
1 | df['A'].plot(color = 'gray')
2 | df.rolling(window = 10, center = False)['A'].apply(lambda x: x[1]/x[2]).plot(color = 'red')
3 |
--------------------------------------------------------------------------------
/snippets/daterange.py:
--------------------------------------------------------------------------------
1 | print(min(data.index))
2 | print(max(data.index))
--------------------------------------------------------------------------------
/snippets/dtwdistance.py:
--------------------------------------------------------------------------------
1 | def DTWDistance(s1, s2):
2 | DTW={}
3 |
4 | for i in range(len(s1)):
5 | DTW[(i, -1)] = float('inf')
6 | for i in range(len(s2)):
7 | DTW[(-1, i)] = float('inf')
8 | DTW[(-1, -1)] = 0
9 |
10 | for i in range(len(s1)):
11 | for j in range(len(s2)):
12 | dist= (s1[i]-s2[j])**2
13 | DTW[(i, j)] = dist + min(DTW[(i-1, j)],DTW[(i, j-1)], DTW[(i-1, j-1)])
14 |
15 | return sqrt(DTW[len(s1)-1, len(s2)-1])
--------------------------------------------------------------------------------
/snippets/euclidedistance.py:
--------------------------------------------------------------------------------
1 | def EuclidDistance(s1, s2):
2 | sum_squares = 0
3 | for i in range(len(s1)):
4 | sum_squares = sum_squares + (s1[i] - s2[i])**2
5 | return sqrt(sum_squares)
--------------------------------------------------------------------------------
/snippets/offset_aliases.py:
--------------------------------------------------------------------------------
1 | pd.date_range(start, periods=10, freq='2h20min')
2 |
--------------------------------------------------------------------------------
/snippets/prac1.py:
--------------------------------------------------------------------------------
1 | f['2012-07':'2012-08'][['High', 'Low']].plot()
--------------------------------------------------------------------------------
/snippets/prac2.py:
--------------------------------------------------------------------------------
1 | r = f.rolling(50).var()['Volume'].plot()
--------------------------------------------------------------------------------
/snippets/prac3.py:
--------------------------------------------------------------------------------
1 | r = f.expanding().var()['Volume'].plot()
--------------------------------------------------------------------------------
/snippets/prac4.py:
--------------------------------------------------------------------------------
1 | lagged = f.shift(1)
2 | sum((f - lagged)['Open'] > 0)
3 | f['DayGain'] = f['Open'] - lagged['Open']
4 | sum(f['DayGain'] > 0)/len(f['DayGain'])
--------------------------------------------------------------------------------
/snippets/prac5.py:
--------------------------------------------------------------------------------
1 | f.rolling(window = 25)['DayGain'].apply(lambda x: len([x_i for x_i in x if x_i > 0])/len(x)).plot()
--------------------------------------------------------------------------------
/snippets/prac6.py:
--------------------------------------------------------------------------------
1 | f.resample('M').mean()['High'].plot()
--------------------------------------------------------------------------------
/snippets/prac7.py:
--------------------------------------------------------------------------------
1 | volume = f.Volume
2 | volume_lagged = f.Volume.shift()
3 | diffed_volume = volume - volume_lagged
4 | diffed_volume.rolling(window = 20).var().plot()
--------------------------------------------------------------------------------
/snippets/prac8.py:
--------------------------------------------------------------------------------
1 | pd.DataFrame({'real':f.Volume, 'lagged':f.Volume.shift()}).corr()
--------------------------------------------------------------------------------
/snippets/readtime.py:
--------------------------------------------------------------------------------
1 | data = pd.read_fwf('data/ao_monthly.txt', header = None, index_col = 0, parse_dates = [[0, 1]], infer_datetime_format = True)
--------------------------------------------------------------------------------
/snippets/resampling_end.py:
--------------------------------------------------------------------------------
1 | # 1
2 | # method = 'None'
3 | # do this perhaps to join to other temporal data
4 |
5 | # 2
6 | # asfreq is more rigid
7 |
8 | # 3
9 | converted.asfreq('10Min', method = None).fillna(method = 'ffill', limit =3)
10 |
11 | # 4
12 | # It's basically like a groupby operation
13 |
--------------------------------------------------------------------------------
/snippets/shift_future.py:
--------------------------------------------------------------------------------
1 | ts = pd.Series(np.random.randn(20), pd.date_range('7/1/16', freq = 'D', periods = 20))
2 | ts_lagged = ts.shift(-1)
3 | plt.plot(ts, color = 'blue')
4 | plt.plot(ts_lagged, color = 'red')
--------------------------------------------------------------------------------
/snippets/startend.py:
--------------------------------------------------------------------------------
1 | p = pd.Period('2016-07')
2 | p.start_time
3 | p.end_time
--------------------------------------------------------------------------------
/snippets/try1.py:
--------------------------------------------------------------------------------
1 | t1 = pd.to_datetime('2016-06-18 12:15pm', dayfirst = True).strftime(format = '%Y/%M/%D')
2 |
3 | t2 = pd.Timestamp('2016-06-18 12:15pm').strftime(format = '%Y/%M/%D')
--------------------------------------------------------------------------------
/snippets/window_funcs_try.py:
--------------------------------------------------------------------------------
1 | #1
2 | ts = pd.Series(np.random.randn(1000), index = pd.date_range(start = '1/1/16', periods = 1000, freq = 'D'))
3 | ts.ewm(span = 60, freq = 'D', min_periods = 0, adjust = True).mean().plot()
4 | ts.rolling(window = 60).mean().plot()
5 |
6 | #2
7 | # To get a more reliable statistic if it makes logical sense
8 |
9 | #3
10 | r = df.rolling(window = 20)
11 | r.apply(lambda x: sorted(x)[round(len(x)*.5)])
12 |
13 | #4
14 | r = df.rolling(window = 20)
15 | r.agg(['sum', 'mean']).head(30)
16 |
--------------------------------------------------------------------------------