You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

numpy_tutorial.ipynb 169 kB

6 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "markdown",
  5. "metadata": {},
  6. "source": [
  7. "# Numpy - multidimensional data arrays"
  8. ]
  9. },
  10. {
  11. "cell_type": "markdown",
  12. "metadata": {},
  13. "source": [
  14. "J.R. Johansson (jrjohansson at gmail.com)\n",
  15. "\n",
  16. "The latest version of this [IPython notebook](http://ipython.org/notebook.html) lecture is available at [http://github.com/jrjohansson/scientific-python-lectures](http://github.com/jrjohansson/scientific-python-lectures).\n",
  17. "\n",
  18. "The other notebooks in this lecture series are indexed at [http://jrjohansson.github.io](http://jrjohansson.github.io)."
  19. ]
  20. },
  21. {
  22. "cell_type": "code",
  23. "execution_count": 1,
  24. "metadata": {},
  25. "outputs": [],
  26. "source": [
  27. "# what is this line all about?!? Answer in lecture 4\n",
  28. "%matplotlib inline\n",
  29. "import matplotlib.pyplot as plt"
  30. ]
  31. },
  32. {
  33. "cell_type": "markdown",
  34. "metadata": {},
  35. "source": [
  36. "## Introduction"
  37. ]
  38. },
  39. {
  40. "cell_type": "markdown",
  41. "metadata": {},
  42. "source": [
  43. "The `numpy` package (module) is used in almost all numerical computation using Python. It is a package that provide high-performance vector, matrix and higher-dimensional data structures for Python. It is implemented in C and Fortran so when calculations are vectorized (formulated with vectors and matrices), performance is very good. \n",
  44. "\n",
  45. "To use `numpy` you need to import the module, using for example:"
  46. ]
  47. },
  48. {
  49. "cell_type": "code",
  50. "execution_count": 2,
  51. "metadata": {},
  52. "outputs": [],
  53. "source": [
  54. "from numpy import *"
  55. ]
  56. },
  57. {
  58. "cell_type": "markdown",
  59. "metadata": {},
  60. "source": [
  61. "In the `numpy` package the terminology used for vectors, matrices and higher-dimensional data sets is *array*. \n",
  62. "\n"
  63. ]
  64. },
  65. {
  66. "cell_type": "markdown",
  67. "metadata": {},
  68. "source": [
  69. "## Creating `numpy` arrays"
  70. ]
  71. },
  72. {
  73. "cell_type": "markdown",
  74. "metadata": {},
  75. "source": [
  76. "There are a number of ways to initialize new numpy arrays, for example from\n",
  77. "\n",
  78. "* a Python list or tuples\n",
  79. "* using functions that are dedicated to generating numpy arrays, such as `arange`, `linspace`, etc.\n",
  80. "* reading data from files"
  81. ]
  82. },
  83. {
  84. "cell_type": "markdown",
  85. "metadata": {},
  86. "source": [
  87. "### From lists"
  88. ]
  89. },
  90. {
  91. "cell_type": "markdown",
  92. "metadata": {},
  93. "source": [
  94. "For example, to create new vector and matrix arrays from Python lists we can use the `numpy.array` function."
  95. ]
  96. },
  97. {
  98. "cell_type": "code",
  99. "execution_count": 3,
  100. "metadata": {},
  101. "outputs": [
  102. {
  103. "data": {
  104. "text/plain": [
  105. "array([1, 2, 3, 4])"
  106. ]
  107. },
  108. "execution_count": 3,
  109. "metadata": {},
  110. "output_type": "execute_result"
  111. }
  112. ],
  113. "source": [
  114. "# a vector: the argument to the array function is a Python list\n",
  115. "v = array([1,2,3,4])\n",
  116. "\n",
  117. "v"
  118. ]
  119. },
  120. {
  121. "cell_type": "code",
  122. "execution_count": 4,
  123. "metadata": {},
  124. "outputs": [
  125. {
  126. "data": {
  127. "text/plain": [
  128. "array([[1, 2],\n",
  129. " [3, 4]])"
  130. ]
  131. },
  132. "execution_count": 4,
  133. "metadata": {},
  134. "output_type": "execute_result"
  135. }
  136. ],
  137. "source": [
  138. "# a matrix: the argument to the array function is a nested Python list\n",
  139. "M = array([[1, 2], [3, 4]])\n",
  140. "\n",
  141. "M"
  142. ]
  143. },
  144. {
  145. "cell_type": "markdown",
  146. "metadata": {},
  147. "source": [
  148. "The `v` and `M` objects are both of the type `ndarray` that the `numpy` module provides."
  149. ]
  150. },
  151. {
  152. "cell_type": "code",
  153. "execution_count": 5,
  154. "metadata": {},
  155. "outputs": [
  156. {
  157. "data": {
  158. "text/plain": [
  159. "(numpy.ndarray, numpy.ndarray)"
  160. ]
  161. },
  162. "execution_count": 5,
  163. "metadata": {},
  164. "output_type": "execute_result"
  165. }
  166. ],
  167. "source": [
  168. "type(v), type(M)"
  169. ]
  170. },
  171. {
  172. "cell_type": "markdown",
  173. "metadata": {},
  174. "source": [
  175. "The difference between the `v` and `M` arrays is only their shapes. We can get information about the shape of an array by using the `ndarray.shape` property."
  176. ]
  177. },
  178. {
  179. "cell_type": "code",
  180. "execution_count": 6,
  181. "metadata": {},
  182. "outputs": [
  183. {
  184. "data": {
  185. "text/plain": [
  186. "(4,)"
  187. ]
  188. },
  189. "execution_count": 6,
  190. "metadata": {},
  191. "output_type": "execute_result"
  192. }
  193. ],
  194. "source": [
  195. "v.shape"
  196. ]
  197. },
  198. {
  199. "cell_type": "code",
  200. "execution_count": 7,
  201. "metadata": {},
  202. "outputs": [
  203. {
  204. "data": {
  205. "text/plain": [
  206. "(2, 2)"
  207. ]
  208. },
  209. "execution_count": 7,
  210. "metadata": {},
  211. "output_type": "execute_result"
  212. }
  213. ],
  214. "source": [
  215. "M.shape"
  216. ]
  217. },
  218. {
  219. "cell_type": "markdown",
  220. "metadata": {},
  221. "source": [
  222. "The number of elements in the array is available through the `ndarray.size` property:"
  223. ]
  224. },
  225. {
  226. "cell_type": "code",
  227. "execution_count": 8,
  228. "metadata": {},
  229. "outputs": [
  230. {
  231. "data": {
  232. "text/plain": [
  233. "4"
  234. ]
  235. },
  236. "execution_count": 8,
  237. "metadata": {},
  238. "output_type": "execute_result"
  239. }
  240. ],
  241. "source": [
  242. "M.size"
  243. ]
  244. },
  245. {
  246. "cell_type": "markdown",
  247. "metadata": {},
  248. "source": [
  249. "Equivalently, we could use the function `numpy.shape` and `numpy.size`"
  250. ]
  251. },
  252. {
  253. "cell_type": "code",
  254. "execution_count": 9,
  255. "metadata": {},
  256. "outputs": [
  257. {
  258. "data": {
  259. "text/plain": [
  260. "(2, 2)"
  261. ]
  262. },
  263. "execution_count": 9,
  264. "metadata": {},
  265. "output_type": "execute_result"
  266. }
  267. ],
  268. "source": [
  269. "shape(M)"
  270. ]
  271. },
  272. {
  273. "cell_type": "code",
  274. "execution_count": 10,
  275. "metadata": {},
  276. "outputs": [
  277. {
  278. "data": {
  279. "text/plain": [
  280. "4"
  281. ]
  282. },
  283. "execution_count": 10,
  284. "metadata": {},
  285. "output_type": "execute_result"
  286. }
  287. ],
  288. "source": [
  289. "size(M)"
  290. ]
  291. },
  292. {
  293. "cell_type": "markdown",
  294. "metadata": {},
  295. "source": [
  296. "So far the `numpy.ndarray` looks awefully much like a Python list (or nested list). Why not simply use Python lists for computations instead of creating a new array type? \n",
  297. "\n",
  298. "There are several reasons:\n",
  299. "\n",
  300. "* Python lists are very general. They can contain any kind of object. They are dynamically typed. They do not support mathematical functions such as matrix and dot multiplications, etc. Implementing such functions for Python lists would not be very efficient because of the dynamic typing.\n",
  301. "* Numpy arrays are **statically typed** and **homogeneous**. The type of the elements is determined when the array is created.\n",
  302. "* Numpy arrays are memory efficient.\n",
  303. "* Because of the static typing, fast implementation of mathematical functions such as multiplication and addition of `numpy` arrays can be implemented in a compiled language (C and Fortran is used).\n",
  304. "\n",
  305. "Using the `dtype` (data type) property of an `ndarray`, we can see what type the data of an array has:"
  306. ]
  307. },
  308. {
  309. "cell_type": "code",
  310. "execution_count": 11,
  311. "metadata": {},
  312. "outputs": [
  313. {
  314. "data": {
  315. "text/plain": [
  316. "dtype('int64')"
  317. ]
  318. },
  319. "execution_count": 11,
  320. "metadata": {},
  321. "output_type": "execute_result"
  322. }
  323. ],
  324. "source": [
  325. "M.dtype"
  326. ]
  327. },
  328. {
  329. "cell_type": "markdown",
  330. "metadata": {},
  331. "source": [
  332. "We get an error if we try to assign a value of the wrong type to an element in a numpy array:"
  333. ]
  334. },
  335. {
  336. "cell_type": "code",
  337. "execution_count": 12,
  338. "metadata": {},
  339. "outputs": [
  340. {
  341. "ename": "ValueError",
  342. "evalue": "invalid literal for long() with base 10: 'hello'",
  343. "output_type": "error",
  344. "traceback": [
  345. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  346. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  347. "\u001b[0;32m<ipython-input-12-a09d72434238>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mM\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"hello\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
  348. "\u001b[0;31mValueError\u001b[0m: invalid literal for long() with base 10: 'hello'"
  349. ]
  350. }
  351. ],
  352. "source": [
  353. "M[0,0] = \"hello\""
  354. ]
  355. },
  356. {
  357. "cell_type": "markdown",
  358. "metadata": {},
  359. "source": [
  360. "If we want, we can explicitly define the type of the array data when we create it, using the `dtype` keyword argument: "
  361. ]
  362. },
  363. {
  364. "cell_type": "code",
  365. "execution_count": 13,
  366. "metadata": {},
  367. "outputs": [
  368. {
  369. "data": {
  370. "text/plain": [
  371. "array([[ 1.+0.j, 2.+0.j],\n",
  372. " [ 3.+0.j, 4.+0.j]])"
  373. ]
  374. },
  375. "execution_count": 13,
  376. "metadata": {},
  377. "output_type": "execute_result"
  378. }
  379. ],
  380. "source": [
  381. "M = array([[1, 2], [3, 4]], dtype=complex)\n",
  382. "\n",
  383. "M"
  384. ]
  385. },
  386. {
  387. "cell_type": "markdown",
  388. "metadata": {},
  389. "source": [
  390. "Common data types that can be used with `dtype` are: `int`, `float`, `complex`, `bool`, `object`, etc.\n",
  391. "\n",
  392. "We can also explicitly define the bit size of the data types, for example: `int64`, `int16`, `float128`, `complex128`."
  393. ]
  394. },
  395. {
  396. "cell_type": "markdown",
  397. "metadata": {},
  398. "source": [
  399. "### Using array-generating functions"
  400. ]
  401. },
  402. {
  403. "cell_type": "markdown",
  404. "metadata": {},
  405. "source": [
  406. "For larger arrays it is inpractical to initialize the data manually, using explicit python lists. Instead we can use one of the many functions in `numpy` that generate arrays of different forms. Some of the more common are:"
  407. ]
  408. },
  409. {
  410. "cell_type": "markdown",
  411. "metadata": {},
  412. "source": [
  413. "#### arange"
  414. ]
  415. },
  416. {
  417. "cell_type": "code",
  418. "execution_count": 14,
  419. "metadata": {},
  420. "outputs": [
  421. {
  422. "data": {
  423. "text/plain": [
  424. "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
  425. ]
  426. },
  427. "execution_count": 14,
  428. "metadata": {},
  429. "output_type": "execute_result"
  430. }
  431. ],
  432. "source": [
  433. "# create a range\n",
  434. "\n",
  435. "x = arange(0, 10, 1) # arguments: start, stop, step\n",
  436. "\n",
  437. "x"
  438. ]
  439. },
  440. {
  441. "cell_type": "code",
  442. "execution_count": 15,
  443. "metadata": {},
  444. "outputs": [
  445. {
  446. "data": {
  447. "text/plain": [
  448. "array([ -1.00000000e+00, -9.00000000e-01, -8.00000000e-01,\n",
  449. " -7.00000000e-01, -6.00000000e-01, -5.00000000e-01,\n",
  450. " -4.00000000e-01, -3.00000000e-01, -2.00000000e-01,\n",
  451. " -1.00000000e-01, -2.22044605e-16, 1.00000000e-01,\n",
  452. " 2.00000000e-01, 3.00000000e-01, 4.00000000e-01,\n",
  453. " 5.00000000e-01, 6.00000000e-01, 7.00000000e-01,\n",
  454. " 8.00000000e-01, 9.00000000e-01])"
  455. ]
  456. },
  457. "execution_count": 15,
  458. "metadata": {},
  459. "output_type": "execute_result"
  460. }
  461. ],
  462. "source": [
  463. "x = arange(-1, 1, 0.1)\n",
  464. "\n",
  465. "x"
  466. ]
  467. },
  468. {
  469. "cell_type": "markdown",
  470. "metadata": {},
  471. "source": [
  472. "#### linspace and logspace"
  473. ]
  474. },
  475. {
  476. "cell_type": "code",
  477. "execution_count": 16,
  478. "metadata": {},
  479. "outputs": [
  480. {
  481. "data": {
  482. "text/plain": [
  483. "array([ 0. , 0.41666667, 0.83333333, 1.25 ,\n",
  484. " 1.66666667, 2.08333333, 2.5 , 2.91666667,\n",
  485. " 3.33333333, 3.75 , 4.16666667, 4.58333333,\n",
  486. " 5. , 5.41666667, 5.83333333, 6.25 ,\n",
  487. " 6.66666667, 7.08333333, 7.5 , 7.91666667,\n",
  488. " 8.33333333, 8.75 , 9.16666667, 9.58333333, 10. ])"
  489. ]
  490. },
  491. "execution_count": 16,
  492. "metadata": {},
  493. "output_type": "execute_result"
  494. }
  495. ],
  496. "source": [
  497. "# using linspace, both end points ARE included\n",
  498. "linspace(0, 10, 25)"
  499. ]
  500. },
  501. {
  502. "cell_type": "code",
  503. "execution_count": 17,
  504. "metadata": {},
  505. "outputs": [
  506. {
  507. "data": {
  508. "text/plain": [
  509. "array([ 1.00000000e+00, 3.03773178e+00, 9.22781435e+00,\n",
  510. " 2.80316249e+01, 8.51525577e+01, 2.58670631e+02,\n",
  511. " 7.85771994e+02, 2.38696456e+03, 7.25095809e+03,\n",
  512. " 2.20264658e+04])"
  513. ]
  514. },
  515. "execution_count": 17,
  516. "metadata": {},
  517. "output_type": "execute_result"
  518. }
  519. ],
  520. "source": [
  521. "logspace(0, 10, 10, base=e)"
  522. ]
  523. },
  524. {
  525. "cell_type": "markdown",
  526. "metadata": {},
  527. "source": [
  528. "#### mgrid"
  529. ]
  530. },
  531. {
  532. "cell_type": "code",
  533. "execution_count": 18,
  534. "metadata": {},
  535. "outputs": [],
  536. "source": [
  537. "x, y = mgrid[0:5, 0:5] # similar to meshgrid in MATLAB"
  538. ]
  539. },
  540. {
  541. "cell_type": "code",
  542. "execution_count": 19,
  543. "metadata": {},
  544. "outputs": [
  545. {
  546. "data": {
  547. "text/plain": [
  548. "array([[0, 0, 0, 0, 0],\n",
  549. " [1, 1, 1, 1, 1],\n",
  550. " [2, 2, 2, 2, 2],\n",
  551. " [3, 3, 3, 3, 3],\n",
  552. " [4, 4, 4, 4, 4]])"
  553. ]
  554. },
  555. "execution_count": 19,
  556. "metadata": {},
  557. "output_type": "execute_result"
  558. }
  559. ],
  560. "source": [
  561. "x"
  562. ]
  563. },
  564. {
  565. "cell_type": "code",
  566. "execution_count": 20,
  567. "metadata": {},
  568. "outputs": [
  569. {
  570. "data": {
  571. "text/plain": [
  572. "array([[0, 1, 2, 3, 4],\n",
  573. " [0, 1, 2, 3, 4],\n",
  574. " [0, 1, 2, 3, 4],\n",
  575. " [0, 1, 2, 3, 4],\n",
  576. " [0, 1, 2, 3, 4]])"
  577. ]
  578. },
  579. "execution_count": 20,
  580. "metadata": {},
  581. "output_type": "execute_result"
  582. }
  583. ],
  584. "source": [
  585. "y"
  586. ]
  587. },
  588. {
  589. "cell_type": "markdown",
  590. "metadata": {},
  591. "source": [
  592. "#### random data"
  593. ]
  594. },
  595. {
  596. "cell_type": "code",
  597. "execution_count": 21,
  598. "metadata": {},
  599. "outputs": [],
  600. "source": [
  601. "from numpy import random"
  602. ]
  603. },
  604. {
  605. "cell_type": "code",
  606. "execution_count": 22,
  607. "metadata": {},
  608. "outputs": [
  609. {
  610. "data": {
  611. "text/plain": [
  612. "array([[ 0.92932506, 0.19684255, 0.736434 , 0.18125714, 0.70905038],\n",
  613. " [ 0.18803573, 0.9312815 , 0.1284532 , 0.38138008, 0.36646481],\n",
  614. " [ 0.53700462, 0.02361381, 0.97760688, 0.73296701, 0.23042324],\n",
  615. " [ 0.9024635 , 0.20860922, 0.67729644, 0.68386687, 0.49385729],\n",
  616. " [ 0.95876515, 0.29341553, 0.37520629, 0.29194432, 0.64102804]])"
  617. ]
  618. },
  619. "execution_count": 22,
  620. "metadata": {},
  621. "output_type": "execute_result"
  622. }
  623. ],
  624. "source": [
  625. "# uniform random numbers in [0,1]\n",
  626. "random.rand(5,5)"
  627. ]
  628. },
  629. {
  630. "cell_type": "code",
  631. "execution_count": 23,
  632. "metadata": {},
  633. "outputs": [
  634. {
  635. "data": {
  636. "text/plain": [
  637. "array([[ 0.117907 , -1.57016164, 0.78256246, 1.45386709, 0.54744436],\n",
  638. " [ 2.30356897, -0.28352021, -0.9087325 , 1.2285279 , -1.00760167],\n",
  639. " [ 0.72216801, 0.77507299, -0.37793178, -0.31852241, 0.84493629],\n",
  640. " [-0.10682252, 1.15930142, -0.47291444, -0.69496967, -0.58912034],\n",
  641. " [ 0.34513487, -0.92389516, -0.216978 , 0.42153272, 0.86650101]])"
  642. ]
  643. },
  644. "execution_count": 23,
  645. "metadata": {},
  646. "output_type": "execute_result"
  647. }
  648. ],
  649. "source": [
  650. "# standard normal distributed random numbers\n",
  651. "random.randn(5,5)"
  652. ]
  653. },
  654. {
  655. "cell_type": "markdown",
  656. "metadata": {},
  657. "source": [
  658. "#### diag"
  659. ]
  660. },
  661. {
  662. "cell_type": "code",
  663. "execution_count": 24,
  664. "metadata": {},
  665. "outputs": [
  666. {
  667. "data": {
  668. "text/plain": [
  669. "array([[1, 0, 0],\n",
  670. " [0, 2, 0],\n",
  671. " [0, 0, 3]])"
  672. ]
  673. },
  674. "execution_count": 24,
  675. "metadata": {},
  676. "output_type": "execute_result"
  677. }
  678. ],
  679. "source": [
  680. "# a diagonal matrix\n",
  681. "diag([1,2,3])"
  682. ]
  683. },
  684. {
  685. "cell_type": "code",
  686. "execution_count": 25,
  687. "metadata": {},
  688. "outputs": [
  689. {
  690. "data": {
  691. "text/plain": [
  692. "array([[0, 1, 0, 0],\n",
  693. " [0, 0, 2, 0],\n",
  694. " [0, 0, 0, 3],\n",
  695. " [0, 0, 0, 0]])"
  696. ]
  697. },
  698. "execution_count": 25,
  699. "metadata": {},
  700. "output_type": "execute_result"
  701. }
  702. ],
  703. "source": [
  704. "# diagonal with offset from the main diagonal\n",
  705. "diag([1,2,3], k=1) "
  706. ]
  707. },
  708. {
  709. "cell_type": "markdown",
  710. "metadata": {},
  711. "source": [
  712. "#### zeros and ones"
  713. ]
  714. },
  715. {
  716. "cell_type": "code",
  717. "execution_count": 26,
  718. "metadata": {},
  719. "outputs": [
  720. {
  721. "data": {
  722. "text/plain": [
  723. "array([[ 0., 0., 0.],\n",
  724. " [ 0., 0., 0.],\n",
  725. " [ 0., 0., 0.]])"
  726. ]
  727. },
  728. "execution_count": 26,
  729. "metadata": {},
  730. "output_type": "execute_result"
  731. }
  732. ],
  733. "source": [
  734. "zeros((3,3))"
  735. ]
  736. },
  737. {
  738. "cell_type": "code",
  739. "execution_count": 27,
  740. "metadata": {},
  741. "outputs": [
  742. {
  743. "data": {
  744. "text/plain": [
  745. "array([[ 1., 1., 1.],\n",
  746. " [ 1., 1., 1.],\n",
  747. " [ 1., 1., 1.]])"
  748. ]
  749. },
  750. "execution_count": 27,
  751. "metadata": {},
  752. "output_type": "execute_result"
  753. }
  754. ],
  755. "source": [
  756. "ones((3,3))"
  757. ]
  758. },
  759. {
  760. "cell_type": "markdown",
  761. "metadata": {},
  762. "source": [
  763. "## File I/O"
  764. ]
  765. },
  766. {
  767. "cell_type": "markdown",
  768. "metadata": {},
  769. "source": [
  770. "### Comma-separated values (CSV)"
  771. ]
  772. },
  773. {
  774. "cell_type": "markdown",
  775. "metadata": {},
  776. "source": [
  777. "A very common file format for data files is comma-separated values (CSV), or related formats such as TSV (tab-separated values). To read data from such files into Numpy arrays we can use the `numpy.genfromtxt` function. For example, "
  778. ]
  779. },
  780. {
  781. "cell_type": "code",
  782. "execution_count": 28,
  783. "metadata": {},
  784. "outputs": [
  785. {
  786. "name": "stdout",
  787. "output_type": "stream",
  788. "text": [
  789. "1800 1 1 -6.1 -6.1 -6.1 1\r\n",
  790. "1800 1 2 -15.4 -15.4 -15.4 1\r\n",
  791. "1800 1 3 -15.0 -15.0 -15.0 1\r\n",
  792. "1800 1 4 -19.3 -19.3 -19.3 1\r\n",
  793. "1800 1 5 -16.8 -16.8 -16.8 1\r\n",
  794. "1800 1 6 -11.4 -11.4 -11.4 1\r\n",
  795. "1800 1 7 -7.6 -7.6 -7.6 1\r\n",
  796. "1800 1 8 -7.1 -7.1 -7.1 1\r\n",
  797. "1800 1 9 -10.1 -10.1 -10.1 1\r\n",
  798. "1800 1 10 -9.5 -9.5 -9.5 1\r\n"
  799. ]
  800. }
  801. ],
  802. "source": [
  803. "!head stockholm_td_adj.dat"
  804. ]
  805. },
  806. {
  807. "cell_type": "code",
  808. "execution_count": 29,
  809. "metadata": {},
  810. "outputs": [],
  811. "source": [
  812. "data = genfromtxt('stockholm_td_adj.dat')"
  813. ]
  814. },
  815. {
  816. "cell_type": "code",
  817. "execution_count": 30,
  818. "metadata": {},
  819. "outputs": [
  820. {
  821. "data": {
  822. "text/plain": [
  823. "(77431, 7)"
  824. ]
  825. },
  826. "execution_count": 30,
  827. "metadata": {},
  828. "output_type": "execute_result"
  829. }
  830. ],
  831. "source": [
  832. "data.shape"
  833. ]
  834. },
  835. {
  836. "cell_type": "code",
  837. "execution_count": 31,
  838. "metadata": {},
  839. "outputs": [
  840. {
  841. "data": {
  842. "image/png": "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\n",
  843. "text/plain": [
  844. "<matplotlib.figure.Figure at 0x108686390>"
  845. ]
  846. },
  847. "metadata": {},
  848. "output_type": "display_data"
  849. }
  850. ],
  851. "source": [
  852. "fig, ax = plt.subplots(figsize=(14,4))\n",
  853. "ax.plot(data[:,0]+data[:,1]/12.0+data[:,2]/365, data[:,5])\n",
  854. "ax.axis('tight')\n",
  855. "ax.set_title('tempeatures in Stockholm')\n",
  856. "ax.set_xlabel('year')\n",
  857. "ax.set_ylabel('temperature (C)');"
  858. ]
  859. },
  860. {
  861. "cell_type": "markdown",
  862. "metadata": {},
  863. "source": [
  864. "Using `numpy.savetxt` we can store a Numpy array to a file in CSV format:"
  865. ]
  866. },
  867. {
  868. "cell_type": "code",
  869. "execution_count": 32,
  870. "metadata": {},
  871. "outputs": [
  872. {
  873. "data": {
  874. "text/plain": [
  875. "array([[ 0.77872576, 0.40043577, 0.66254019],\n",
  876. " [ 0.60410063, 0.4791374 , 0.8237106 ],\n",
  877. " [ 0.96856318, 0.15459644, 0.96082399]])"
  878. ]
  879. },
  880. "execution_count": 32,
  881. "metadata": {},
  882. "output_type": "execute_result"
  883. }
  884. ],
  885. "source": [
  886. "M = random.rand(3,3)\n",
  887. "\n",
  888. "M"
  889. ]
  890. },
  891. {
  892. "cell_type": "code",
  893. "execution_count": 33,
  894. "metadata": {},
  895. "outputs": [],
  896. "source": [
  897. "savetxt(\"random-matrix.csv\", M)"
  898. ]
  899. },
  900. {
  901. "cell_type": "code",
  902. "execution_count": 34,
  903. "metadata": {},
  904. "outputs": [
  905. {
  906. "name": "stdout",
  907. "output_type": "stream",
  908. "text": [
  909. "7.787257639287014088e-01 4.004357670697732408e-01 6.625401863466899854e-01\r\n",
  910. "6.041006328761111543e-01 4.791373994963619154e-01 8.237105968088237473e-01\r\n",
  911. "9.685631757740569281e-01 1.545964379103705877e-01 9.608239852111523094e-01\r\n"
  912. ]
  913. }
  914. ],
  915. "source": [
  916. "!cat random-matrix.csv"
  917. ]
  918. },
  919. {
  920. "cell_type": "code",
  921. "execution_count": 35,
  922. "metadata": {},
  923. "outputs": [
  924. {
  925. "name": "stdout",
  926. "output_type": "stream",
  927. "text": [
  928. "0.77873 0.40044 0.66254\r\n",
  929. "0.60410 0.47914 0.82371\r\n",
  930. "0.96856 0.15460 0.96082\r\n"
  931. ]
  932. }
  933. ],
  934. "source": [
  935. "savetxt(\"random-matrix.csv\", M, fmt='%.5f') # fmt specifies the format\n",
  936. "\n",
  937. "!cat random-matrix.csv"
  938. ]
  939. },
  940. {
  941. "cell_type": "markdown",
  942. "metadata": {},
  943. "source": [
  944. "### Numpy's native file format"
  945. ]
  946. },
  947. {
  948. "cell_type": "markdown",
  949. "metadata": {},
  950. "source": [
  951. "Useful when storing and reading back numpy array data. Use the functions `numpy.save` and `numpy.load`:"
  952. ]
  953. },
  954. {
  955. "cell_type": "code",
  956. "execution_count": 36,
  957. "metadata": {},
  958. "outputs": [
  959. {
  960. "name": "stdout",
  961. "output_type": "stream",
  962. "text": [
  963. "random-matrix.npy: data\r\n"
  964. ]
  965. }
  966. ],
  967. "source": [
  968. "save(\"random-matrix.npy\", M)\n",
  969. "\n",
  970. "!file random-matrix.npy"
  971. ]
  972. },
  973. {
  974. "cell_type": "code",
  975. "execution_count": 37,
  976. "metadata": {},
  977. "outputs": [
  978. {
  979. "data": {
  980. "text/plain": [
  981. "array([[ 0.77872576, 0.40043577, 0.66254019],\n",
  982. " [ 0.60410063, 0.4791374 , 0.8237106 ],\n",
  983. " [ 0.96856318, 0.15459644, 0.96082399]])"
  984. ]
  985. },
  986. "execution_count": 37,
  987. "metadata": {},
  988. "output_type": "execute_result"
  989. }
  990. ],
  991. "source": [
  992. "load(\"random-matrix.npy\")"
  993. ]
  994. },
  995. {
  996. "cell_type": "markdown",
  997. "metadata": {},
  998. "source": [
  999. "## More properties of the numpy arrays"
  1000. ]
  1001. },
  1002. {
  1003. "cell_type": "code",
  1004. "execution_count": 38,
  1005. "metadata": {},
  1006. "outputs": [
  1007. {
  1008. "data": {
  1009. "text/plain": [
  1010. "8"
  1011. ]
  1012. },
  1013. "execution_count": 38,
  1014. "metadata": {},
  1015. "output_type": "execute_result"
  1016. }
  1017. ],
  1018. "source": [
  1019. "M.itemsize # bytes per element"
  1020. ]
  1021. },
  1022. {
  1023. "cell_type": "code",
  1024. "execution_count": 39,
  1025. "metadata": {},
  1026. "outputs": [
  1027. {
  1028. "data": {
  1029. "text/plain": [
  1030. "72"
  1031. ]
  1032. },
  1033. "execution_count": 39,
  1034. "metadata": {},
  1035. "output_type": "execute_result"
  1036. }
  1037. ],
  1038. "source": [
  1039. "M.nbytes # number of bytes"
  1040. ]
  1041. },
  1042. {
  1043. "cell_type": "code",
  1044. "execution_count": 40,
  1045. "metadata": {},
  1046. "outputs": [
  1047. {
  1048. "data": {
  1049. "text/plain": [
  1050. "2"
  1051. ]
  1052. },
  1053. "execution_count": 40,
  1054. "metadata": {},
  1055. "output_type": "execute_result"
  1056. }
  1057. ],
  1058. "source": [
  1059. "M.ndim # number of dimensions"
  1060. ]
  1061. },
  1062. {
  1063. "cell_type": "markdown",
  1064. "metadata": {},
  1065. "source": [
  1066. "## Manipulating arrays"
  1067. ]
  1068. },
  1069. {
  1070. "cell_type": "markdown",
  1071. "metadata": {},
  1072. "source": [
  1073. "### Indexing"
  1074. ]
  1075. },
  1076. {
  1077. "cell_type": "markdown",
  1078. "metadata": {},
  1079. "source": [
  1080. "We can index elements in an array using square brackets and indices:"
  1081. ]
  1082. },
  1083. {
  1084. "cell_type": "code",
  1085. "execution_count": 41,
  1086. "metadata": {},
  1087. "outputs": [
  1088. {
  1089. "data": {
  1090. "text/plain": [
  1091. "1"
  1092. ]
  1093. },
  1094. "execution_count": 41,
  1095. "metadata": {},
  1096. "output_type": "execute_result"
  1097. }
  1098. ],
  1099. "source": [
  1100. "# v is a vector, and has only one dimension, taking one index\n",
  1101. "v[0]"
  1102. ]
  1103. },
  1104. {
  1105. "cell_type": "code",
  1106. "execution_count": 42,
  1107. "metadata": {},
  1108. "outputs": [
  1109. {
  1110. "data": {
  1111. "text/plain": [
  1112. "0.47913739949636192"
  1113. ]
  1114. },
  1115. "execution_count": 42,
  1116. "metadata": {},
  1117. "output_type": "execute_result"
  1118. }
  1119. ],
  1120. "source": [
  1121. "# M is a matrix, or a 2 dimensional array, taking two indices \n",
  1122. "M[1,1]"
  1123. ]
  1124. },
  1125. {
  1126. "cell_type": "markdown",
  1127. "metadata": {},
  1128. "source": [
  1129. "If we omit an index of a multidimensional array it returns the whole row (or, in general, a N-1 dimensional array) "
  1130. ]
  1131. },
  1132. {
  1133. "cell_type": "code",
  1134. "execution_count": 43,
  1135. "metadata": {},
  1136. "outputs": [
  1137. {
  1138. "data": {
  1139. "text/plain": [
  1140. "array([[ 0.77872576, 0.40043577, 0.66254019],\n",
  1141. " [ 0.60410063, 0.4791374 , 0.8237106 ],\n",
  1142. " [ 0.96856318, 0.15459644, 0.96082399]])"
  1143. ]
  1144. },
  1145. "execution_count": 43,
  1146. "metadata": {},
  1147. "output_type": "execute_result"
  1148. }
  1149. ],
  1150. "source": [
  1151. "M"
  1152. ]
  1153. },
  1154. {
  1155. "cell_type": "code",
  1156. "execution_count": 44,
  1157. "metadata": {},
  1158. "outputs": [
  1159. {
  1160. "data": {
  1161. "text/plain": [
  1162. "array([ 0.60410063, 0.4791374 , 0.8237106 ])"
  1163. ]
  1164. },
  1165. "execution_count": 44,
  1166. "metadata": {},
  1167. "output_type": "execute_result"
  1168. }
  1169. ],
  1170. "source": [
  1171. "M[1]"
  1172. ]
  1173. },
  1174. {
  1175. "cell_type": "markdown",
  1176. "metadata": {},
  1177. "source": [
  1178. "The same thing can be achieved with using `:` instead of an index: "
  1179. ]
  1180. },
  1181. {
  1182. "cell_type": "code",
  1183. "execution_count": 45,
  1184. "metadata": {},
  1185. "outputs": [
  1186. {
  1187. "data": {
  1188. "text/plain": [
  1189. "array([ 0.60410063, 0.4791374 , 0.8237106 ])"
  1190. ]
  1191. },
  1192. "execution_count": 45,
  1193. "metadata": {},
  1194. "output_type": "execute_result"
  1195. }
  1196. ],
  1197. "source": [
  1198. "M[1,:] # row 1"
  1199. ]
  1200. },
  1201. {
  1202. "cell_type": "code",
  1203. "execution_count": 46,
  1204. "metadata": {},
  1205. "outputs": [
  1206. {
  1207. "data": {
  1208. "text/plain": [
  1209. "array([ 0.40043577, 0.4791374 , 0.15459644])"
  1210. ]
  1211. },
  1212. "execution_count": 46,
  1213. "metadata": {},
  1214. "output_type": "execute_result"
  1215. }
  1216. ],
  1217. "source": [
  1218. "M[:,1] # column 1"
  1219. ]
  1220. },
  1221. {
  1222. "cell_type": "markdown",
  1223. "metadata": {},
  1224. "source": [
  1225. "We can assign new values to elements in an array using indexing:"
  1226. ]
  1227. },
  1228. {
  1229. "cell_type": "code",
  1230. "execution_count": 47,
  1231. "metadata": {},
  1232. "outputs": [],
  1233. "source": [
  1234. "M[0,0] = 1"
  1235. ]
  1236. },
  1237. {
  1238. "cell_type": "code",
  1239. "execution_count": 48,
  1240. "metadata": {},
  1241. "outputs": [
  1242. {
  1243. "data": {
  1244. "text/plain": [
  1245. "array([[ 1. , 0.40043577, 0.66254019],\n",
  1246. " [ 0.60410063, 0.4791374 , 0.8237106 ],\n",
  1247. " [ 0.96856318, 0.15459644, 0.96082399]])"
  1248. ]
  1249. },
  1250. "execution_count": 48,
  1251. "metadata": {},
  1252. "output_type": "execute_result"
  1253. }
  1254. ],
  1255. "source": [
  1256. "M"
  1257. ]
  1258. },
  1259. {
  1260. "cell_type": "code",
  1261. "execution_count": 49,
  1262. "metadata": {},
  1263. "outputs": [],
  1264. "source": [
  1265. "# also works for rows and columns\n",
  1266. "M[1,:] = 0\n",
  1267. "M[:,2] = -1"
  1268. ]
  1269. },
  1270. {
  1271. "cell_type": "code",
  1272. "execution_count": 50,
  1273. "metadata": {},
  1274. "outputs": [
  1275. {
  1276. "data": {
  1277. "text/plain": [
  1278. "array([[ 1. , 0.40043577, -1. ],\n",
  1279. " [ 0. , 0. , -1. ],\n",
  1280. " [ 0.96856318, 0.15459644, -1. ]])"
  1281. ]
  1282. },
  1283. "execution_count": 50,
  1284. "metadata": {},
  1285. "output_type": "execute_result"
  1286. }
  1287. ],
  1288. "source": [
  1289. "M"
  1290. ]
  1291. },
  1292. {
  1293. "cell_type": "markdown",
  1294. "metadata": {},
  1295. "source": [
  1296. "### Index slicing"
  1297. ]
  1298. },
  1299. {
  1300. "cell_type": "markdown",
  1301. "metadata": {},
  1302. "source": [
  1303. "Index slicing is the technical name for the syntax `M[lower:upper:step]` to extract part of an array:"
  1304. ]
  1305. },
  1306. {
  1307. "cell_type": "code",
  1308. "execution_count": 51,
  1309. "metadata": {},
  1310. "outputs": [
  1311. {
  1312. "data": {
  1313. "text/plain": [
  1314. "array([1, 2, 3, 4, 5])"
  1315. ]
  1316. },
  1317. "execution_count": 51,
  1318. "metadata": {},
  1319. "output_type": "execute_result"
  1320. }
  1321. ],
  1322. "source": [
  1323. "A = array([1,2,3,4,5])\n",
  1324. "A"
  1325. ]
  1326. },
  1327. {
  1328. "cell_type": "code",
  1329. "execution_count": 52,
  1330. "metadata": {},
  1331. "outputs": [
  1332. {
  1333. "data": {
  1334. "text/plain": [
  1335. "array([2, 3])"
  1336. ]
  1337. },
  1338. "execution_count": 52,
  1339. "metadata": {},
  1340. "output_type": "execute_result"
  1341. }
  1342. ],
  1343. "source": [
  1344. "A[1:3]"
  1345. ]
  1346. },
  1347. {
  1348. "cell_type": "markdown",
  1349. "metadata": {},
  1350. "source": [
  1351. "Array slices are *mutable*: if they are assigned a new value the original array from which the slice was extracted is modified:"
  1352. ]
  1353. },
  1354. {
  1355. "cell_type": "code",
  1356. "execution_count": 53,
  1357. "metadata": {},
  1358. "outputs": [
  1359. {
  1360. "data": {
  1361. "text/plain": [
  1362. "array([ 1, -2, -3, 4, 5])"
  1363. ]
  1364. },
  1365. "execution_count": 53,
  1366. "metadata": {},
  1367. "output_type": "execute_result"
  1368. }
  1369. ],
  1370. "source": [
  1371. "A[1:3] = [-2,-3]\n",
  1372. "\n",
  1373. "A"
  1374. ]
  1375. },
  1376. {
  1377. "cell_type": "markdown",
  1378. "metadata": {},
  1379. "source": [
  1380. "We can omit any of the three parameters in `M[lower:upper:step]`:"
  1381. ]
  1382. },
  1383. {
  1384. "cell_type": "code",
  1385. "execution_count": 54,
  1386. "metadata": {},
  1387. "outputs": [
  1388. {
  1389. "data": {
  1390. "text/plain": [
  1391. "array([ 1, -2, -3, 4, 5])"
  1392. ]
  1393. },
  1394. "execution_count": 54,
  1395. "metadata": {},
  1396. "output_type": "execute_result"
  1397. }
  1398. ],
  1399. "source": [
  1400. "A[::] # lower, upper, step all take the default values"
  1401. ]
  1402. },
  1403. {
  1404. "cell_type": "code",
  1405. "execution_count": 55,
  1406. "metadata": {},
  1407. "outputs": [
  1408. {
  1409. "data": {
  1410. "text/plain": [
  1411. "array([ 1, -3, 5])"
  1412. ]
  1413. },
  1414. "execution_count": 55,
  1415. "metadata": {},
  1416. "output_type": "execute_result"
  1417. }
  1418. ],
  1419. "source": [
  1420. "A[::2] # step is 2, lower and upper defaults to the beginning and end of the array"
  1421. ]
  1422. },
  1423. {
  1424. "cell_type": "code",
  1425. "execution_count": 56,
  1426. "metadata": {},
  1427. "outputs": [
  1428. {
  1429. "data": {
  1430. "text/plain": [
  1431. "array([ 1, -2, -3])"
  1432. ]
  1433. },
  1434. "execution_count": 56,
  1435. "metadata": {},
  1436. "output_type": "execute_result"
  1437. }
  1438. ],
  1439. "source": [
  1440. "A[:3] # first three elements"
  1441. ]
  1442. },
  1443. {
  1444. "cell_type": "code",
  1445. "execution_count": 57,
  1446. "metadata": {},
  1447. "outputs": [
  1448. {
  1449. "data": {
  1450. "text/plain": [
  1451. "array([4, 5])"
  1452. ]
  1453. },
  1454. "execution_count": 57,
  1455. "metadata": {},
  1456. "output_type": "execute_result"
  1457. }
  1458. ],
  1459. "source": [
  1460. "A[3:] # elements from index 3"
  1461. ]
  1462. },
  1463. {
  1464. "cell_type": "markdown",
  1465. "metadata": {},
  1466. "source": [
  1467. "Negative indices counts from the end of the array (positive index from the begining):"
  1468. ]
  1469. },
  1470. {
  1471. "cell_type": "code",
  1472. "execution_count": 58,
  1473. "metadata": {},
  1474. "outputs": [],
  1475. "source": [
  1476. "A = array([1,2,3,4,5])"
  1477. ]
  1478. },
  1479. {
  1480. "cell_type": "code",
  1481. "execution_count": 59,
  1482. "metadata": {},
  1483. "outputs": [
  1484. {
  1485. "data": {
  1486. "text/plain": [
  1487. "5"
  1488. ]
  1489. },
  1490. "execution_count": 59,
  1491. "metadata": {},
  1492. "output_type": "execute_result"
  1493. }
  1494. ],
  1495. "source": [
  1496. "A[-1] # the last element in the array"
  1497. ]
  1498. },
  1499. {
  1500. "cell_type": "code",
  1501. "execution_count": 60,
  1502. "metadata": {},
  1503. "outputs": [
  1504. {
  1505. "data": {
  1506. "text/plain": [
  1507. "array([3, 4, 5])"
  1508. ]
  1509. },
  1510. "execution_count": 60,
  1511. "metadata": {},
  1512. "output_type": "execute_result"
  1513. }
  1514. ],
  1515. "source": [
  1516. "A[-3:] # the last three elements"
  1517. ]
  1518. },
  1519. {
  1520. "cell_type": "markdown",
  1521. "metadata": {},
  1522. "source": [
  1523. "Index slicing works exactly the same way for multidimensional arrays:"
  1524. ]
  1525. },
  1526. {
  1527. "cell_type": "code",
  1528. "execution_count": 61,
  1529. "metadata": {},
  1530. "outputs": [
  1531. {
  1532. "data": {
  1533. "text/plain": [
  1534. "array([[ 0, 1, 2, 3, 4],\n",
  1535. " [10, 11, 12, 13, 14],\n",
  1536. " [20, 21, 22, 23, 24],\n",
  1537. " [30, 31, 32, 33, 34],\n",
  1538. " [40, 41, 42, 43, 44]])"
  1539. ]
  1540. },
  1541. "execution_count": 61,
  1542. "metadata": {},
  1543. "output_type": "execute_result"
  1544. }
  1545. ],
  1546. "source": [
  1547. "A = array([[n+m*10 for n in range(5)] for m in range(5)])\n",
  1548. "\n",
  1549. "A"
  1550. ]
  1551. },
  1552. {
  1553. "cell_type": "code",
  1554. "execution_count": 62,
  1555. "metadata": {},
  1556. "outputs": [
  1557. {
  1558. "data": {
  1559. "text/plain": [
  1560. "array([[11, 12, 13],\n",
  1561. " [21, 22, 23],\n",
  1562. " [31, 32, 33]])"
  1563. ]
  1564. },
  1565. "execution_count": 62,
  1566. "metadata": {},
  1567. "output_type": "execute_result"
  1568. }
  1569. ],
  1570. "source": [
  1571. "# a block from the original array\n",
  1572. "A[1:4, 1:4]"
  1573. ]
  1574. },
  1575. {
  1576. "cell_type": "code",
  1577. "execution_count": 63,
  1578. "metadata": {},
  1579. "outputs": [
  1580. {
  1581. "data": {
  1582. "text/plain": [
  1583. "array([[ 0, 2, 4],\n",
  1584. " [20, 22, 24],\n",
  1585. " [40, 42, 44]])"
  1586. ]
  1587. },
  1588. "execution_count": 63,
  1589. "metadata": {},
  1590. "output_type": "execute_result"
  1591. }
  1592. ],
  1593. "source": [
  1594. "# strides\n",
  1595. "A[::2, ::2]"
  1596. ]
  1597. },
  1598. {
  1599. "cell_type": "markdown",
  1600. "metadata": {},
  1601. "source": [
  1602. "### Fancy indexing"
  1603. ]
  1604. },
  1605. {
  1606. "cell_type": "markdown",
  1607. "metadata": {},
  1608. "source": [
  1609. "Fancy indexing is the name for when an array or list is used in-place of an index: "
  1610. ]
  1611. },
  1612. {
  1613. "cell_type": "code",
  1614. "execution_count": 64,
  1615. "metadata": {},
  1616. "outputs": [
  1617. {
  1618. "data": {
  1619. "text/plain": [
  1620. "array([[10, 11, 12, 13, 14],\n",
  1621. " [20, 21, 22, 23, 24],\n",
  1622. " [30, 31, 32, 33, 34]])"
  1623. ]
  1624. },
  1625. "execution_count": 64,
  1626. "metadata": {},
  1627. "output_type": "execute_result"
  1628. }
  1629. ],
  1630. "source": [
  1631. "row_indices = [1, 2, 3]\n",
  1632. "A[row_indices]"
  1633. ]
  1634. },
  1635. {
  1636. "cell_type": "code",
  1637. "execution_count": 65,
  1638. "metadata": {},
  1639. "outputs": [
  1640. {
  1641. "data": {
  1642. "text/plain": [
  1643. "array([11, 22, 34])"
  1644. ]
  1645. },
  1646. "execution_count": 65,
  1647. "metadata": {},
  1648. "output_type": "execute_result"
  1649. }
  1650. ],
  1651. "source": [
  1652. "col_indices = [1, 2, -1] # remember, index -1 means the last element\n",
  1653. "A[row_indices, col_indices]"
  1654. ]
  1655. },
  1656. {
  1657. "cell_type": "markdown",
  1658. "metadata": {},
  1659. "source": [
  1660. "We can also use index masks: If the index mask is an Numpy array of data type `bool`, then an element is selected (True) or not (False) depending on the value of the index mask at the position of each element: "
  1661. ]
  1662. },
  1663. {
  1664. "cell_type": "code",
  1665. "execution_count": 66,
  1666. "metadata": {},
  1667. "outputs": [
  1668. {
  1669. "data": {
  1670. "text/plain": [
  1671. "array([0, 1, 2, 3, 4])"
  1672. ]
  1673. },
  1674. "execution_count": 66,
  1675. "metadata": {},
  1676. "output_type": "execute_result"
  1677. }
  1678. ],
  1679. "source": [
  1680. "B = array([n for n in range(5)])\n",
  1681. "B"
  1682. ]
  1683. },
  1684. {
  1685. "cell_type": "code",
  1686. "execution_count": 67,
  1687. "metadata": {},
  1688. "outputs": [
  1689. {
  1690. "data": {
  1691. "text/plain": [
  1692. "array([0, 2])"
  1693. ]
  1694. },
  1695. "execution_count": 67,
  1696. "metadata": {},
  1697. "output_type": "execute_result"
  1698. }
  1699. ],
  1700. "source": [
  1701. "row_mask = array([True, False, True, False, False])\n",
  1702. "B[row_mask]"
  1703. ]
  1704. },
  1705. {
  1706. "cell_type": "code",
  1707. "execution_count": 68,
  1708. "metadata": {},
  1709. "outputs": [
  1710. {
  1711. "data": {
  1712. "text/plain": [
  1713. "array([0, 2])"
  1714. ]
  1715. },
  1716. "execution_count": 68,
  1717. "metadata": {},
  1718. "output_type": "execute_result"
  1719. }
  1720. ],
  1721. "source": [
  1722. "# same thing\n",
  1723. "row_mask = array([1,0,1,0,0], dtype=bool)\n",
  1724. "B[row_mask]"
  1725. ]
  1726. },
  1727. {
  1728. "cell_type": "markdown",
  1729. "metadata": {},
  1730. "source": [
  1731. "This feature is very useful to conditionally select elements from an array, using for example comparison operators:"
  1732. ]
  1733. },
  1734. {
  1735. "cell_type": "code",
  1736. "execution_count": 69,
  1737. "metadata": {},
  1738. "outputs": [
  1739. {
  1740. "data": {
  1741. "text/plain": [
  1742. "array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ,\n",
  1743. " 5.5, 6. , 6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5])"
  1744. ]
  1745. },
  1746. "execution_count": 69,
  1747. "metadata": {},
  1748. "output_type": "execute_result"
  1749. }
  1750. ],
  1751. "source": [
  1752. "x = arange(0, 10, 0.5)\n",
  1753. "x"
  1754. ]
  1755. },
  1756. {
  1757. "cell_type": "code",
  1758. "execution_count": 70,
  1759. "metadata": {},
  1760. "outputs": [
  1761. {
  1762. "data": {
  1763. "text/plain": [
  1764. "array([False, False, False, False, False, False, False, False, False,\n",
  1765. " False, False, True, True, True, True, False, False, False,\n",
  1766. " False, False], dtype=bool)"
  1767. ]
  1768. },
  1769. "execution_count": 70,
  1770. "metadata": {},
  1771. "output_type": "execute_result"
  1772. }
  1773. ],
  1774. "source": [
  1775. "mask = (5 < x) * (x < 7.5)\n",
  1776. "\n",
  1777. "mask"
  1778. ]
  1779. },
  1780. {
  1781. "cell_type": "code",
  1782. "execution_count": 71,
  1783. "metadata": {},
  1784. "outputs": [
  1785. {
  1786. "data": {
  1787. "text/plain": [
  1788. "array([ 5.5, 6. , 6.5, 7. ])"
  1789. ]
  1790. },
  1791. "execution_count": 71,
  1792. "metadata": {},
  1793. "output_type": "execute_result"
  1794. }
  1795. ],
  1796. "source": [
  1797. "x[mask]"
  1798. ]
  1799. },
  1800. {
  1801. "cell_type": "markdown",
  1802. "metadata": {},
  1803. "source": [
  1804. "## Functions for extracting data from arrays and creating arrays"
  1805. ]
  1806. },
  1807. {
  1808. "cell_type": "markdown",
  1809. "metadata": {},
  1810. "source": [
  1811. "### where"
  1812. ]
  1813. },
  1814. {
  1815. "cell_type": "markdown",
  1816. "metadata": {},
  1817. "source": [
  1818. "The index mask can be converted to position index using the `where` function"
  1819. ]
  1820. },
  1821. {
  1822. "cell_type": "code",
  1823. "execution_count": 72,
  1824. "metadata": {},
  1825. "outputs": [
  1826. {
  1827. "data": {
  1828. "text/plain": [
  1829. "(array([11, 12, 13, 14]),)"
  1830. ]
  1831. },
  1832. "execution_count": 72,
  1833. "metadata": {},
  1834. "output_type": "execute_result"
  1835. }
  1836. ],
  1837. "source": [
  1838. "indices = where(mask)\n",
  1839. "\n",
  1840. "indices"
  1841. ]
  1842. },
  1843. {
  1844. "cell_type": "code",
  1845. "execution_count": 73,
  1846. "metadata": {},
  1847. "outputs": [
  1848. {
  1849. "data": {
  1850. "text/plain": [
  1851. "array([ 5.5, 6. , 6.5, 7. ])"
  1852. ]
  1853. },
  1854. "execution_count": 73,
  1855. "metadata": {},
  1856. "output_type": "execute_result"
  1857. }
  1858. ],
  1859. "source": [
  1860. "x[indices] # this indexing is equivalent to the fancy indexing x[mask]"
  1861. ]
  1862. },
  1863. {
  1864. "cell_type": "markdown",
  1865. "metadata": {},
  1866. "source": [
  1867. "### diag"
  1868. ]
  1869. },
  1870. {
  1871. "cell_type": "markdown",
  1872. "metadata": {},
  1873. "source": [
  1874. "With the diag function we can also extract the diagonal and subdiagonals of an array:"
  1875. ]
  1876. },
  1877. {
  1878. "cell_type": "code",
  1879. "execution_count": 74,
  1880. "metadata": {},
  1881. "outputs": [
  1882. {
  1883. "data": {
  1884. "text/plain": [
  1885. "array([ 0, 11, 22, 33, 44])"
  1886. ]
  1887. },
  1888. "execution_count": 74,
  1889. "metadata": {},
  1890. "output_type": "execute_result"
  1891. }
  1892. ],
  1893. "source": [
  1894. "diag(A)"
  1895. ]
  1896. },
  1897. {
  1898. "cell_type": "code",
  1899. "execution_count": 75,
  1900. "metadata": {},
  1901. "outputs": [
  1902. {
  1903. "data": {
  1904. "text/plain": [
  1905. "array([10, 21, 32, 43])"
  1906. ]
  1907. },
  1908. "execution_count": 75,
  1909. "metadata": {},
  1910. "output_type": "execute_result"
  1911. }
  1912. ],
  1913. "source": [
  1914. "diag(A, -1)"
  1915. ]
  1916. },
  1917. {
  1918. "cell_type": "markdown",
  1919. "metadata": {},
  1920. "source": [
  1921. "### take"
  1922. ]
  1923. },
  1924. {
  1925. "cell_type": "markdown",
  1926. "metadata": {},
  1927. "source": [
  1928. "The `take` function is similar to fancy indexing described above:"
  1929. ]
  1930. },
  1931. {
  1932. "cell_type": "code",
  1933. "execution_count": 76,
  1934. "metadata": {},
  1935. "outputs": [
  1936. {
  1937. "data": {
  1938. "text/plain": [
  1939. "array([-3, -2, -1, 0, 1, 2])"
  1940. ]
  1941. },
  1942. "execution_count": 76,
  1943. "metadata": {},
  1944. "output_type": "execute_result"
  1945. }
  1946. ],
  1947. "source": [
  1948. "v2 = arange(-3,3)\n",
  1949. "v2"
  1950. ]
  1951. },
  1952. {
  1953. "cell_type": "code",
  1954. "execution_count": 77,
  1955. "metadata": {},
  1956. "outputs": [
  1957. {
  1958. "data": {
  1959. "text/plain": [
  1960. "array([-2, 0, 2])"
  1961. ]
  1962. },
  1963. "execution_count": 77,
  1964. "metadata": {},
  1965. "output_type": "execute_result"
  1966. }
  1967. ],
  1968. "source": [
  1969. "row_indices = [1, 3, 5]\n",
  1970. "v2[row_indices] # fancy indexing"
  1971. ]
  1972. },
  1973. {
  1974. "cell_type": "code",
  1975. "execution_count": 78,
  1976. "metadata": {},
  1977. "outputs": [
  1978. {
  1979. "data": {
  1980. "text/plain": [
  1981. "array([-2, 0, 2])"
  1982. ]
  1983. },
  1984. "execution_count": 78,
  1985. "metadata": {},
  1986. "output_type": "execute_result"
  1987. }
  1988. ],
  1989. "source": [
  1990. "v2.take(row_indices)"
  1991. ]
  1992. },
  1993. {
  1994. "cell_type": "markdown",
  1995. "metadata": {},
  1996. "source": [
  1997. "But `take` also works on lists and other objects:"
  1998. ]
  1999. },
  2000. {
  2001. "cell_type": "code",
  2002. "execution_count": 79,
  2003. "metadata": {},
  2004. "outputs": [
  2005. {
  2006. "data": {
  2007. "text/plain": [
  2008. "array([-2, 0, 2])"
  2009. ]
  2010. },
  2011. "execution_count": 79,
  2012. "metadata": {},
  2013. "output_type": "execute_result"
  2014. }
  2015. ],
  2016. "source": [
  2017. "take([-3, -2, -1, 0, 1, 2], row_indices)"
  2018. ]
  2019. },
  2020. {
  2021. "cell_type": "markdown",
  2022. "metadata": {},
  2023. "source": [
  2024. "### choose"
  2025. ]
  2026. },
  2027. {
  2028. "cell_type": "markdown",
  2029. "metadata": {},
  2030. "source": [
  2031. "Constructs an array by picking elements from several arrays:"
  2032. ]
  2033. },
  2034. {
  2035. "cell_type": "code",
  2036. "execution_count": 80,
  2037. "metadata": {},
  2038. "outputs": [
  2039. {
  2040. "data": {
  2041. "text/plain": [
  2042. "array([ 5, -2, 5, -2])"
  2043. ]
  2044. },
  2045. "execution_count": 80,
  2046. "metadata": {},
  2047. "output_type": "execute_result"
  2048. }
  2049. ],
  2050. "source": [
  2051. "which = [1, 0, 1, 0]\n",
  2052. "choices = [[-2,-2,-2,-2], [5,5,5,5]]\n",
  2053. "\n",
  2054. "choose(which, choices)"
  2055. ]
  2056. },
  2057. {
  2058. "cell_type": "markdown",
  2059. "metadata": {},
  2060. "source": [
  2061. "## Linear algebra"
  2062. ]
  2063. },
  2064. {
  2065. "cell_type": "markdown",
  2066. "metadata": {},
  2067. "source": [
  2068. "Vectorizing code is the key to writing efficient numerical calculation with Python/Numpy. That means that as much as possible of a program should be formulated in terms of matrix and vector operations, like matrix-matrix multiplication."
  2069. ]
  2070. },
  2071. {
  2072. "cell_type": "markdown",
  2073. "metadata": {},
  2074. "source": [
  2075. "### Scalar-array operations"
  2076. ]
  2077. },
  2078. {
  2079. "cell_type": "markdown",
  2080. "metadata": {},
  2081. "source": [
  2082. "We can use the usual arithmetic operators to multiply, add, subtract, and divide arrays with scalar numbers."
  2083. ]
  2084. },
  2085. {
  2086. "cell_type": "code",
  2087. "execution_count": 81,
  2088. "metadata": {},
  2089. "outputs": [],
  2090. "source": [
  2091. "v1 = arange(0, 5)"
  2092. ]
  2093. },
  2094. {
  2095. "cell_type": "code",
  2096. "execution_count": 82,
  2097. "metadata": {},
  2098. "outputs": [
  2099. {
  2100. "data": {
  2101. "text/plain": [
  2102. "array([0, 2, 4, 6, 8])"
  2103. ]
  2104. },
  2105. "execution_count": 82,
  2106. "metadata": {},
  2107. "output_type": "execute_result"
  2108. }
  2109. ],
  2110. "source": [
  2111. "v1 * 2"
  2112. ]
  2113. },
  2114. {
  2115. "cell_type": "code",
  2116. "execution_count": 83,
  2117. "metadata": {},
  2118. "outputs": [
  2119. {
  2120. "data": {
  2121. "text/plain": [
  2122. "array([2, 3, 4, 5, 6])"
  2123. ]
  2124. },
  2125. "execution_count": 83,
  2126. "metadata": {},
  2127. "output_type": "execute_result"
  2128. }
  2129. ],
  2130. "source": [
  2131. "v1 + 2"
  2132. ]
  2133. },
  2134. {
  2135. "cell_type": "code",
  2136. "execution_count": 84,
  2137. "metadata": {},
  2138. "outputs": [
  2139. {
  2140. "data": {
  2141. "text/plain": [
  2142. "(array([[ 0, 2, 4, 6, 8],\n",
  2143. " [20, 22, 24, 26, 28],\n",
  2144. " [40, 42, 44, 46, 48],\n",
  2145. " [60, 62, 64, 66, 68],\n",
  2146. " [80, 82, 84, 86, 88]]), array([[ 2, 3, 4, 5, 6],\n",
  2147. " [12, 13, 14, 15, 16],\n",
  2148. " [22, 23, 24, 25, 26],\n",
  2149. " [32, 33, 34, 35, 36],\n",
  2150. " [42, 43, 44, 45, 46]]))"
  2151. ]
  2152. },
  2153. "execution_count": 84,
  2154. "metadata": {},
  2155. "output_type": "execute_result"
  2156. }
  2157. ],
  2158. "source": [
  2159. "A * 2, A + 2"
  2160. ]
  2161. },
  2162. {
  2163. "cell_type": "markdown",
  2164. "metadata": {},
  2165. "source": [
  2166. "### Element-wise array-array operations"
  2167. ]
  2168. },
  2169. {
  2170. "cell_type": "markdown",
  2171. "metadata": {},
  2172. "source": [
  2173. "When we add, subtract, multiply and divide arrays with each other, the default behaviour is **element-wise** operations:"
  2174. ]
  2175. },
  2176. {
  2177. "cell_type": "code",
  2178. "execution_count": 85,
  2179. "metadata": {},
  2180. "outputs": [
  2181. {
  2182. "data": {
  2183. "text/plain": [
  2184. "array([[ 0, 1, 4, 9, 16],\n",
  2185. " [ 100, 121, 144, 169, 196],\n",
  2186. " [ 400, 441, 484, 529, 576],\n",
  2187. " [ 900, 961, 1024, 1089, 1156],\n",
  2188. " [1600, 1681, 1764, 1849, 1936]])"
  2189. ]
  2190. },
  2191. "execution_count": 85,
  2192. "metadata": {},
  2193. "output_type": "execute_result"
  2194. }
  2195. ],
  2196. "source": [
  2197. "A * A # element-wise multiplication"
  2198. ]
  2199. },
  2200. {
  2201. "cell_type": "code",
  2202. "execution_count": 86,
  2203. "metadata": {},
  2204. "outputs": [
  2205. {
  2206. "data": {
  2207. "text/plain": [
  2208. "array([ 0, 1, 4, 9, 16])"
  2209. ]
  2210. },
  2211. "execution_count": 86,
  2212. "metadata": {},
  2213. "output_type": "execute_result"
  2214. }
  2215. ],
  2216. "source": [
  2217. "v1 * v1"
  2218. ]
  2219. },
  2220. {
  2221. "cell_type": "markdown",
  2222. "metadata": {},
  2223. "source": [
  2224. "If we multiply arrays with compatible shapes, we get an element-wise multiplication of each row:"
  2225. ]
  2226. },
  2227. {
  2228. "cell_type": "code",
  2229. "execution_count": 87,
  2230. "metadata": {},
  2231. "outputs": [
  2232. {
  2233. "data": {
  2234. "text/plain": [
  2235. "((5, 5), (5,))"
  2236. ]
  2237. },
  2238. "execution_count": 87,
  2239. "metadata": {},
  2240. "output_type": "execute_result"
  2241. }
  2242. ],
  2243. "source": [
  2244. "A.shape, v1.shape"
  2245. ]
  2246. },
  2247. {
  2248. "cell_type": "code",
  2249. "execution_count": 88,
  2250. "metadata": {},
  2251. "outputs": [
  2252. {
  2253. "data": {
  2254. "text/plain": [
  2255. "array([[ 0, 1, 4, 9, 16],\n",
  2256. " [ 0, 11, 24, 39, 56],\n",
  2257. " [ 0, 21, 44, 69, 96],\n",
  2258. " [ 0, 31, 64, 99, 136],\n",
  2259. " [ 0, 41, 84, 129, 176]])"
  2260. ]
  2261. },
  2262. "execution_count": 88,
  2263. "metadata": {},
  2264. "output_type": "execute_result"
  2265. }
  2266. ],
  2267. "source": [
  2268. "A * v1"
  2269. ]
  2270. },
  2271. {
  2272. "cell_type": "markdown",
  2273. "metadata": {},
  2274. "source": [
  2275. "### Matrix algebra"
  2276. ]
  2277. },
  2278. {
  2279. "cell_type": "markdown",
  2280. "metadata": {},
  2281. "source": [
  2282. "What about matrix mutiplication? There are two ways. We can either use the `dot` function, which applies a matrix-matrix, matrix-vector, or inner vector multiplication to its two arguments: "
  2283. ]
  2284. },
  2285. {
  2286. "cell_type": "code",
  2287. "execution_count": 89,
  2288. "metadata": {},
  2289. "outputs": [
  2290. {
  2291. "data": {
  2292. "text/plain": [
  2293. "array([[ 300, 310, 320, 330, 340],\n",
  2294. " [1300, 1360, 1420, 1480, 1540],\n",
  2295. " [2300, 2410, 2520, 2630, 2740],\n",
  2296. " [3300, 3460, 3620, 3780, 3940],\n",
  2297. " [4300, 4510, 4720, 4930, 5140]])"
  2298. ]
  2299. },
  2300. "execution_count": 89,
  2301. "metadata": {},
  2302. "output_type": "execute_result"
  2303. }
  2304. ],
  2305. "source": [
  2306. "dot(A, A)"
  2307. ]
  2308. },
  2309. {
  2310. "cell_type": "code",
  2311. "execution_count": 90,
  2312. "metadata": {},
  2313. "outputs": [
  2314. {
  2315. "data": {
  2316. "text/plain": [
  2317. "array([ 30, 130, 230, 330, 430])"
  2318. ]
  2319. },
  2320. "execution_count": 90,
  2321. "metadata": {},
  2322. "output_type": "execute_result"
  2323. }
  2324. ],
  2325. "source": [
  2326. "dot(A, v1)"
  2327. ]
  2328. },
  2329. {
  2330. "cell_type": "code",
  2331. "execution_count": 91,
  2332. "metadata": {},
  2333. "outputs": [
  2334. {
  2335. "data": {
  2336. "text/plain": [
  2337. "30"
  2338. ]
  2339. },
  2340. "execution_count": 91,
  2341. "metadata": {},
  2342. "output_type": "execute_result"
  2343. }
  2344. ],
  2345. "source": [
  2346. "dot(v1, v1)"
  2347. ]
  2348. },
  2349. {
  2350. "cell_type": "markdown",
  2351. "metadata": {},
  2352. "source": [
  2353. "Alternatively, we can cast the array objects to the type `matrix`. This changes the behavior of the standard arithmetic operators `+, -, *` to use matrix algebra."
  2354. ]
  2355. },
  2356. {
  2357. "cell_type": "code",
  2358. "execution_count": 92,
  2359. "metadata": {},
  2360. "outputs": [],
  2361. "source": [
  2362. "M = matrix(A)\n",
  2363. "v = matrix(v1).T # make it a column vector"
  2364. ]
  2365. },
  2366. {
  2367. "cell_type": "code",
  2368. "execution_count": 93,
  2369. "metadata": {},
  2370. "outputs": [
  2371. {
  2372. "data": {
  2373. "text/plain": [
  2374. "matrix([[0],\n",
  2375. " [1],\n",
  2376. " [2],\n",
  2377. " [3],\n",
  2378. " [4]])"
  2379. ]
  2380. },
  2381. "execution_count": 93,
  2382. "metadata": {},
  2383. "output_type": "execute_result"
  2384. }
  2385. ],
  2386. "source": [
  2387. "v"
  2388. ]
  2389. },
  2390. {
  2391. "cell_type": "code",
  2392. "execution_count": 94,
  2393. "metadata": {},
  2394. "outputs": [
  2395. {
  2396. "data": {
  2397. "text/plain": [
  2398. "matrix([[ 300, 310, 320, 330, 340],\n",
  2399. " [1300, 1360, 1420, 1480, 1540],\n",
  2400. " [2300, 2410, 2520, 2630, 2740],\n",
  2401. " [3300, 3460, 3620, 3780, 3940],\n",
  2402. " [4300, 4510, 4720, 4930, 5140]])"
  2403. ]
  2404. },
  2405. "execution_count": 94,
  2406. "metadata": {},
  2407. "output_type": "execute_result"
  2408. }
  2409. ],
  2410. "source": [
  2411. "M * M"
  2412. ]
  2413. },
  2414. {
  2415. "cell_type": "code",
  2416. "execution_count": 95,
  2417. "metadata": {},
  2418. "outputs": [
  2419. {
  2420. "data": {
  2421. "text/plain": [
  2422. "matrix([[ 30],\n",
  2423. " [130],\n",
  2424. " [230],\n",
  2425. " [330],\n",
  2426. " [430]])"
  2427. ]
  2428. },
  2429. "execution_count": 95,
  2430. "metadata": {},
  2431. "output_type": "execute_result"
  2432. }
  2433. ],
  2434. "source": [
  2435. "M * v"
  2436. ]
  2437. },
  2438. {
  2439. "cell_type": "code",
  2440. "execution_count": 96,
  2441. "metadata": {},
  2442. "outputs": [
  2443. {
  2444. "data": {
  2445. "text/plain": [
  2446. "matrix([[30]])"
  2447. ]
  2448. },
  2449. "execution_count": 96,
  2450. "metadata": {},
  2451. "output_type": "execute_result"
  2452. }
  2453. ],
  2454. "source": [
  2455. "# inner product\n",
  2456. "v.T * v"
  2457. ]
  2458. },
  2459. {
  2460. "cell_type": "code",
  2461. "execution_count": 97,
  2462. "metadata": {},
  2463. "outputs": [
  2464. {
  2465. "data": {
  2466. "text/plain": [
  2467. "matrix([[ 30],\n",
  2468. " [131],\n",
  2469. " [232],\n",
  2470. " [333],\n",
  2471. " [434]])"
  2472. ]
  2473. },
  2474. "execution_count": 97,
  2475. "metadata": {},
  2476. "output_type": "execute_result"
  2477. }
  2478. ],
  2479. "source": [
  2480. "# with matrix objects, standard matrix algebra applies\n",
  2481. "v + M*v"
  2482. ]
  2483. },
  2484. {
  2485. "cell_type": "markdown",
  2486. "metadata": {},
  2487. "source": [
  2488. "If we try to add, subtract or multiply objects with incomplatible shapes we get an error:"
  2489. ]
  2490. },
  2491. {
  2492. "cell_type": "code",
  2493. "execution_count": 98,
  2494. "metadata": {},
  2495. "outputs": [],
  2496. "source": [
  2497. "v = matrix([1,2,3,4,5,6]).T"
  2498. ]
  2499. },
  2500. {
  2501. "cell_type": "code",
  2502. "execution_count": 99,
  2503. "metadata": {},
  2504. "outputs": [
  2505. {
  2506. "data": {
  2507. "text/plain": [
  2508. "((5, 5), (6, 1))"
  2509. ]
  2510. },
  2511. "execution_count": 99,
  2512. "metadata": {},
  2513. "output_type": "execute_result"
  2514. }
  2515. ],
  2516. "source": [
  2517. "shape(M), shape(v)"
  2518. ]
  2519. },
  2520. {
  2521. "cell_type": "code",
  2522. "execution_count": 100,
  2523. "metadata": {},
  2524. "outputs": [
  2525. {
  2526. "ename": "ValueError",
  2527. "evalue": "shapes (5,5) and (6,1) not aligned: 5 (dim 1) != 6 (dim 0)",
  2528. "output_type": "error",
  2529. "traceback": [
  2530. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  2531. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  2532. "\u001b[0;32m<ipython-input-100-995fb48ad0cc>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mM\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
  2533. "\u001b[0;32m/Users/rob/miniconda/envs/py27-spl/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.pyc\u001b[0m in \u001b[0;36m__mul__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 339\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mN\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 340\u001b[0m \u001b[0;31m# This promotes 1-D vectors to row vectors\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 341\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0masmatrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 342\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misscalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'__rmul__'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mN\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
  2534. "\u001b[0;31mValueError\u001b[0m: shapes (5,5) and (6,1) not aligned: 5 (dim 1) != 6 (dim 0)"
  2535. ]
  2536. }
  2537. ],
  2538. "source": [
  2539. "M * v"
  2540. ]
  2541. },
  2542. {
  2543. "cell_type": "markdown",
  2544. "metadata": {},
  2545. "source": [
  2546. "See also the related functions: `inner`, `outer`, `cross`, `kron`, `tensordot`. Try for example `help(kron)`."
  2547. ]
  2548. },
  2549. {
  2550. "cell_type": "markdown",
  2551. "metadata": {},
  2552. "source": [
  2553. "### Array/Matrix transformations"
  2554. ]
  2555. },
  2556. {
  2557. "cell_type": "markdown",
  2558. "metadata": {},
  2559. "source": [
  2560. "Above we have used the `.T` to transpose the matrix object `v`. We could also have used the `transpose` function to accomplish the same thing. \n",
  2561. "\n",
  2562. "Other mathematical functions that transform matrix objects are:"
  2563. ]
  2564. },
  2565. {
  2566. "cell_type": "code",
  2567. "execution_count": 101,
  2568. "metadata": {},
  2569. "outputs": [
  2570. {
  2571. "data": {
  2572. "text/plain": [
  2573. "matrix([[ 0.+1.j, 0.+2.j],\n",
  2574. " [ 0.+3.j, 0.+4.j]])"
  2575. ]
  2576. },
  2577. "execution_count": 101,
  2578. "metadata": {},
  2579. "output_type": "execute_result"
  2580. }
  2581. ],
  2582. "source": [
  2583. "C = matrix([[1j, 2j], [3j, 4j]])\n",
  2584. "C"
  2585. ]
  2586. },
  2587. {
  2588. "cell_type": "code",
  2589. "execution_count": 102,
  2590. "metadata": {},
  2591. "outputs": [
  2592. {
  2593. "data": {
  2594. "text/plain": [
  2595. "matrix([[ 0.-1.j, 0.-2.j],\n",
  2596. " [ 0.-3.j, 0.-4.j]])"
  2597. ]
  2598. },
  2599. "execution_count": 102,
  2600. "metadata": {},
  2601. "output_type": "execute_result"
  2602. }
  2603. ],
  2604. "source": [
  2605. "conjugate(C)"
  2606. ]
  2607. },
  2608. {
  2609. "cell_type": "markdown",
  2610. "metadata": {},
  2611. "source": [
  2612. "Hermitian conjugate: transpose + conjugate"
  2613. ]
  2614. },
  2615. {
  2616. "cell_type": "code",
  2617. "execution_count": 103,
  2618. "metadata": {},
  2619. "outputs": [
  2620. {
  2621. "data": {
  2622. "text/plain": [
  2623. "matrix([[ 0.-1.j, 0.-3.j],\n",
  2624. " [ 0.-2.j, 0.-4.j]])"
  2625. ]
  2626. },
  2627. "execution_count": 103,
  2628. "metadata": {},
  2629. "output_type": "execute_result"
  2630. }
  2631. ],
  2632. "source": [
  2633. "C.H"
  2634. ]
  2635. },
  2636. {
  2637. "cell_type": "markdown",
  2638. "metadata": {},
  2639. "source": [
  2640. "We can extract the real and imaginary parts of complex-valued arrays using `real` and `imag`:"
  2641. ]
  2642. },
  2643. {
  2644. "cell_type": "code",
  2645. "execution_count": 104,
  2646. "metadata": {},
  2647. "outputs": [
  2648. {
  2649. "data": {
  2650. "text/plain": [
  2651. "matrix([[ 0., 0.],\n",
  2652. " [ 0., 0.]])"
  2653. ]
  2654. },
  2655. "execution_count": 104,
  2656. "metadata": {},
  2657. "output_type": "execute_result"
  2658. }
  2659. ],
  2660. "source": [
  2661. "real(C) # same as: C.real"
  2662. ]
  2663. },
  2664. {
  2665. "cell_type": "code",
  2666. "execution_count": 105,
  2667. "metadata": {},
  2668. "outputs": [
  2669. {
  2670. "data": {
  2671. "text/plain": [
  2672. "matrix([[ 1., 2.],\n",
  2673. " [ 3., 4.]])"
  2674. ]
  2675. },
  2676. "execution_count": 105,
  2677. "metadata": {},
  2678. "output_type": "execute_result"
  2679. }
  2680. ],
  2681. "source": [
  2682. "imag(C) # same as: C.imag"
  2683. ]
  2684. },
  2685. {
  2686. "cell_type": "markdown",
  2687. "metadata": {},
  2688. "source": [
  2689. "Or the complex argument and absolute value"
  2690. ]
  2691. },
  2692. {
  2693. "cell_type": "code",
  2694. "execution_count": 106,
  2695. "metadata": {},
  2696. "outputs": [
  2697. {
  2698. "data": {
  2699. "text/plain": [
  2700. "array([[ 0.78539816, 1.10714872],\n",
  2701. " [ 1.24904577, 1.32581766]])"
  2702. ]
  2703. },
  2704. "execution_count": 106,
  2705. "metadata": {},
  2706. "output_type": "execute_result"
  2707. }
  2708. ],
  2709. "source": [
  2710. "angle(C+1) # heads up MATLAB Users, angle is used instead of arg"
  2711. ]
  2712. },
  2713. {
  2714. "cell_type": "code",
  2715. "execution_count": 107,
  2716. "metadata": {},
  2717. "outputs": [
  2718. {
  2719. "data": {
  2720. "text/plain": [
  2721. "matrix([[ 1., 2.],\n",
  2722. " [ 3., 4.]])"
  2723. ]
  2724. },
  2725. "execution_count": 107,
  2726. "metadata": {},
  2727. "output_type": "execute_result"
  2728. }
  2729. ],
  2730. "source": [
  2731. "abs(C)"
  2732. ]
  2733. },
  2734. {
  2735. "cell_type": "markdown",
  2736. "metadata": {},
  2737. "source": [
  2738. "### Matrix computations"
  2739. ]
  2740. },
  2741. {
  2742. "cell_type": "markdown",
  2743. "metadata": {},
  2744. "source": [
  2745. "#### Inverse"
  2746. ]
  2747. },
  2748. {
  2749. "cell_type": "code",
  2750. "execution_count": 108,
  2751. "metadata": {},
  2752. "outputs": [
  2753. {
  2754. "data": {
  2755. "text/plain": [
  2756. "matrix([[ 0.+2.j , 0.-1.j ],\n",
  2757. " [ 0.-1.5j, 0.+0.5j]])"
  2758. ]
  2759. },
  2760. "execution_count": 108,
  2761. "metadata": {},
  2762. "output_type": "execute_result"
  2763. }
  2764. ],
  2765. "source": [
  2766. "linalg.inv(C) # equivalent to C.I "
  2767. ]
  2768. },
  2769. {
  2770. "cell_type": "code",
  2771. "execution_count": 109,
  2772. "metadata": {},
  2773. "outputs": [
  2774. {
  2775. "data": {
  2776. "text/plain": [
  2777. "matrix([[ 1.00000000e+00+0.j, 4.44089210e-16+0.j],\n",
  2778. " [ 0.00000000e+00+0.j, 1.00000000e+00+0.j]])"
  2779. ]
  2780. },
  2781. "execution_count": 109,
  2782. "metadata": {},
  2783. "output_type": "execute_result"
  2784. }
  2785. ],
  2786. "source": [
  2787. "C.I * C"
  2788. ]
  2789. },
  2790. {
  2791. "cell_type": "markdown",
  2792. "metadata": {},
  2793. "source": [
  2794. "#### Determinant"
  2795. ]
  2796. },
  2797. {
  2798. "cell_type": "code",
  2799. "execution_count": 110,
  2800. "metadata": {},
  2801. "outputs": [
  2802. {
  2803. "data": {
  2804. "text/plain": [
  2805. "(2.0000000000000004+0j)"
  2806. ]
  2807. },
  2808. "execution_count": 110,
  2809. "metadata": {},
  2810. "output_type": "execute_result"
  2811. }
  2812. ],
  2813. "source": [
  2814. "linalg.det(C)"
  2815. ]
  2816. },
  2817. {
  2818. "cell_type": "code",
  2819. "execution_count": 111,
  2820. "metadata": {},
  2821. "outputs": [
  2822. {
  2823. "data": {
  2824. "text/plain": [
  2825. "(0.50000000000000011+0j)"
  2826. ]
  2827. },
  2828. "execution_count": 111,
  2829. "metadata": {},
  2830. "output_type": "execute_result"
  2831. }
  2832. ],
  2833. "source": [
  2834. "linalg.det(C.I)"
  2835. ]
  2836. },
  2837. {
  2838. "cell_type": "markdown",
  2839. "metadata": {},
  2840. "source": [
  2841. "### Data processing"
  2842. ]
  2843. },
  2844. {
  2845. "cell_type": "markdown",
  2846. "metadata": {},
  2847. "source": [
  2848. "Often it is useful to store datasets in Numpy arrays. Numpy provides a number of functions to calculate statistics of datasets in arrays. \n",
  2849. "\n",
  2850. "For example, let's calculate some properties from the Stockholm temperature dataset used above."
  2851. ]
  2852. },
  2853. {
  2854. "cell_type": "code",
  2855. "execution_count": 112,
  2856. "metadata": {},
  2857. "outputs": [
  2858. {
  2859. "data": {
  2860. "text/plain": [
  2861. "(77431, 7)"
  2862. ]
  2863. },
  2864. "execution_count": 112,
  2865. "metadata": {},
  2866. "output_type": "execute_result"
  2867. }
  2868. ],
  2869. "source": [
  2870. "# reminder, the tempeature dataset is stored in the data variable:\n",
  2871. "shape(data)"
  2872. ]
  2873. },
  2874. {
  2875. "cell_type": "markdown",
  2876. "metadata": {},
  2877. "source": [
  2878. "#### mean"
  2879. ]
  2880. },
  2881. {
  2882. "cell_type": "code",
  2883. "execution_count": 113,
  2884. "metadata": {},
  2885. "outputs": [
  2886. {
  2887. "data": {
  2888. "text/plain": [
  2889. "6.1971096847515854"
  2890. ]
  2891. },
  2892. "execution_count": 113,
  2893. "metadata": {},
  2894. "output_type": "execute_result"
  2895. }
  2896. ],
  2897. "source": [
  2898. "# the temperature data is in column 3\n",
  2899. "mean(data[:,3])"
  2900. ]
  2901. },
  2902. {
  2903. "cell_type": "markdown",
  2904. "metadata": {},
  2905. "source": [
  2906. "The daily mean temperature in Stockholm over the last 200 years has been about 6.2 C."
  2907. ]
  2908. },
  2909. {
  2910. "cell_type": "markdown",
  2911. "metadata": {},
  2912. "source": [
  2913. "#### standard deviations and variance"
  2914. ]
  2915. },
  2916. {
  2917. "cell_type": "code",
  2918. "execution_count": 114,
  2919. "metadata": {},
  2920. "outputs": [
  2921. {
  2922. "data": {
  2923. "text/plain": [
  2924. "(8.2822716213405734, 68.596023209663414)"
  2925. ]
  2926. },
  2927. "execution_count": 114,
  2928. "metadata": {},
  2929. "output_type": "execute_result"
  2930. }
  2931. ],
  2932. "source": [
  2933. "std(data[:,3]), var(data[:,3])"
  2934. ]
  2935. },
  2936. {
  2937. "cell_type": "markdown",
  2938. "metadata": {},
  2939. "source": [
  2940. "#### min and max"
  2941. ]
  2942. },
  2943. {
  2944. "cell_type": "code",
  2945. "execution_count": 115,
  2946. "metadata": {},
  2947. "outputs": [
  2948. {
  2949. "data": {
  2950. "text/plain": [
  2951. "-25.800000000000001"
  2952. ]
  2953. },
  2954. "execution_count": 115,
  2955. "metadata": {},
  2956. "output_type": "execute_result"
  2957. }
  2958. ],
  2959. "source": [
  2960. "# lowest daily average temperature\n",
  2961. "data[:,3].min()"
  2962. ]
  2963. },
  2964. {
  2965. "cell_type": "code",
  2966. "execution_count": 116,
  2967. "metadata": {},
  2968. "outputs": [
  2969. {
  2970. "data": {
  2971. "text/plain": [
  2972. "28.300000000000001"
  2973. ]
  2974. },
  2975. "execution_count": 116,
  2976. "metadata": {},
  2977. "output_type": "execute_result"
  2978. }
  2979. ],
  2980. "source": [
  2981. "# highest daily average temperature\n",
  2982. "data[:,3].max()"
  2983. ]
  2984. },
  2985. {
  2986. "cell_type": "markdown",
  2987. "metadata": {},
  2988. "source": [
  2989. "#### sum, prod, and trace"
  2990. ]
  2991. },
  2992. {
  2993. "cell_type": "code",
  2994. "execution_count": 117,
  2995. "metadata": {},
  2996. "outputs": [
  2997. {
  2998. "data": {
  2999. "text/plain": [
  3000. "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
  3001. ]
  3002. },
  3003. "execution_count": 117,
  3004. "metadata": {},
  3005. "output_type": "execute_result"
  3006. }
  3007. ],
  3008. "source": [
  3009. "d = arange(0, 10)\n",
  3010. "d"
  3011. ]
  3012. },
  3013. {
  3014. "cell_type": "code",
  3015. "execution_count": 118,
  3016. "metadata": {},
  3017. "outputs": [
  3018. {
  3019. "data": {
  3020. "text/plain": [
  3021. "45"
  3022. ]
  3023. },
  3024. "execution_count": 118,
  3025. "metadata": {},
  3026. "output_type": "execute_result"
  3027. }
  3028. ],
  3029. "source": [
  3030. "# sum up all elements\n",
  3031. "sum(d)"
  3032. ]
  3033. },
  3034. {
  3035. "cell_type": "code",
  3036. "execution_count": 119,
  3037. "metadata": {},
  3038. "outputs": [
  3039. {
  3040. "data": {
  3041. "text/plain": [
  3042. "3628800"
  3043. ]
  3044. },
  3045. "execution_count": 119,
  3046. "metadata": {},
  3047. "output_type": "execute_result"
  3048. }
  3049. ],
  3050. "source": [
  3051. "# product of all elements\n",
  3052. "prod(d+1)"
  3053. ]
  3054. },
  3055. {
  3056. "cell_type": "code",
  3057. "execution_count": 120,
  3058. "metadata": {},
  3059. "outputs": [
  3060. {
  3061. "data": {
  3062. "text/plain": [
  3063. "array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45])"
  3064. ]
  3065. },
  3066. "execution_count": 120,
  3067. "metadata": {},
  3068. "output_type": "execute_result"
  3069. }
  3070. ],
  3071. "source": [
  3072. "# cummulative sum\n",
  3073. "cumsum(d)"
  3074. ]
  3075. },
  3076. {
  3077. "cell_type": "code",
  3078. "execution_count": 121,
  3079. "metadata": {},
  3080. "outputs": [
  3081. {
  3082. "data": {
  3083. "text/plain": [
  3084. "array([ 1, 2, 6, 24, 120, 720, 5040,\n",
  3085. " 40320, 362880, 3628800])"
  3086. ]
  3087. },
  3088. "execution_count": 121,
  3089. "metadata": {},
  3090. "output_type": "execute_result"
  3091. }
  3092. ],
  3093. "source": [
  3094. "# cummulative product\n",
  3095. "cumprod(d+1)"
  3096. ]
  3097. },
  3098. {
  3099. "cell_type": "code",
  3100. "execution_count": 122,
  3101. "metadata": {},
  3102. "outputs": [
  3103. {
  3104. "data": {
  3105. "text/plain": [
  3106. "110"
  3107. ]
  3108. },
  3109. "execution_count": 122,
  3110. "metadata": {},
  3111. "output_type": "execute_result"
  3112. }
  3113. ],
  3114. "source": [
  3115. "# same as: diag(A).sum()\n",
  3116. "trace(A)"
  3117. ]
  3118. },
  3119. {
  3120. "cell_type": "markdown",
  3121. "metadata": {},
  3122. "source": [
  3123. "### Computations on subsets of arrays"
  3124. ]
  3125. },
  3126. {
  3127. "cell_type": "markdown",
  3128. "metadata": {},
  3129. "source": [
  3130. "We can compute with subsets of the data in an array using indexing, fancy indexing, and the other methods of extracting data from an array (described above).\n",
  3131. "\n",
  3132. "For example, let's go back to the temperature dataset:"
  3133. ]
  3134. },
  3135. {
  3136. "cell_type": "code",
  3137. "execution_count": 123,
  3138. "metadata": {},
  3139. "outputs": [
  3140. {
  3141. "name": "stdout",
  3142. "output_type": "stream",
  3143. "text": [
  3144. "1800 1 1 -6.1 -6.1 -6.1 1\r\n",
  3145. "1800 1 2 -15.4 -15.4 -15.4 1\r\n",
  3146. "1800 1 3 -15.0 -15.0 -15.0 1\r\n"
  3147. ]
  3148. }
  3149. ],
  3150. "source": [
  3151. "!head -n 3 stockholm_td_adj.dat"
  3152. ]
  3153. },
  3154. {
  3155. "cell_type": "markdown",
  3156. "metadata": {},
  3157. "source": [
  3158. "The dataformat is: year, month, day, daily average temperature, low, high, location.\n",
  3159. "\n",
  3160. "If we are interested in the average temperature only in a particular month, say February, then we can create a index mask and use it to select only the data for that month using:"
  3161. ]
  3162. },
  3163. {
  3164. "cell_type": "code",
  3165. "execution_count": 124,
  3166. "metadata": {},
  3167. "outputs": [
  3168. {
  3169. "data": {
  3170. "text/plain": [
  3171. "array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.,\n",
  3172. " 12.])"
  3173. ]
  3174. },
  3175. "execution_count": 124,
  3176. "metadata": {},
  3177. "output_type": "execute_result"
  3178. }
  3179. ],
  3180. "source": [
  3181. "unique(data[:,1]) # the month column takes values from 1 to 12"
  3182. ]
  3183. },
  3184. {
  3185. "cell_type": "code",
  3186. "execution_count": 125,
  3187. "metadata": {},
  3188. "outputs": [],
  3189. "source": [
  3190. "mask_feb = data[:,1] == 2"
  3191. ]
  3192. },
  3193. {
  3194. "cell_type": "code",
  3195. "execution_count": 126,
  3196. "metadata": {},
  3197. "outputs": [
  3198. {
  3199. "data": {
  3200. "text/plain": [
  3201. "-3.2121095707365961"
  3202. ]
  3203. },
  3204. "execution_count": 126,
  3205. "metadata": {},
  3206. "output_type": "execute_result"
  3207. }
  3208. ],
  3209. "source": [
  3210. "# the temperature data is in column 3\n",
  3211. "mean(data[mask_feb,3])"
  3212. ]
  3213. },
  3214. {
  3215. "cell_type": "markdown",
  3216. "metadata": {},
  3217. "source": [
  3218. "With these tools we have very powerful data processing capabilities at our disposal. For example, to extract the average monthly average temperatures for each month of the year only takes a few lines of code: "
  3219. ]
  3220. },
  3221. {
  3222. "cell_type": "code",
  3223. "execution_count": 127,
  3224. "metadata": {},
  3225. "outputs": [
  3226. {
  3227. "data": {
  3228. "image/png": "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\nPBJXRXkAAAAASUVORK5CYII=\n",
  3229. "text/plain": [
  3230. "<matplotlib.figure.Figure at 0x109f94e50>"
  3231. ]
  3232. },
  3233. "metadata": {},
  3234. "output_type": "display_data"
  3235. }
  3236. ],
  3237. "source": [
  3238. "months = arange(1,13)\n",
  3239. "monthly_mean = [mean(data[data[:,1] == month, 3]) for month in months]\n",
  3240. "\n",
  3241. "fig, ax = plt.subplots()\n",
  3242. "ax.bar(months, monthly_mean)\n",
  3243. "ax.set_xlabel(\"Month\")\n",
  3244. "ax.set_ylabel(\"Monthly avg. temp.\");"
  3245. ]
  3246. },
  3247. {
  3248. "cell_type": "markdown",
  3249. "metadata": {},
  3250. "source": [
  3251. "### Calculations with higher-dimensional data"
  3252. ]
  3253. },
  3254. {
  3255. "cell_type": "markdown",
  3256. "metadata": {},
  3257. "source": [
  3258. "When functions such as `min`, `max`, etc. are applied to a multidimensional arrays, it is sometimes useful to apply the calculation to the entire array, and sometimes only on a row or column basis. Using the `axis` argument we can specify how these functions should behave: "
  3259. ]
  3260. },
  3261. {
  3262. "cell_type": "code",
  3263. "execution_count": 128,
  3264. "metadata": {},
  3265. "outputs": [
  3266. {
  3267. "data": {
  3268. "text/plain": [
  3269. "array([[ 0.2850926 , 0.17302017, 0.17748378],\n",
  3270. " [ 0.80070487, 0.45527067, 0.61277451],\n",
  3271. " [ 0.11372793, 0.43608703, 0.87010206]])"
  3272. ]
  3273. },
  3274. "execution_count": 128,
  3275. "metadata": {},
  3276. "output_type": "execute_result"
  3277. }
  3278. ],
  3279. "source": [
  3280. "m = random.rand(3,3)\n",
  3281. "m"
  3282. ]
  3283. },
  3284. {
  3285. "cell_type": "code",
  3286. "execution_count": 129,
  3287. "metadata": {},
  3288. "outputs": [
  3289. {
  3290. "data": {
  3291. "text/plain": [
  3292. "0.87010206156754955"
  3293. ]
  3294. },
  3295. "execution_count": 129,
  3296. "metadata": {},
  3297. "output_type": "execute_result"
  3298. }
  3299. ],
  3300. "source": [
  3301. "# global max\n",
  3302. "m.max()"
  3303. ]
  3304. },
  3305. {
  3306. "cell_type": "code",
  3307. "execution_count": 130,
  3308. "metadata": {},
  3309. "outputs": [
  3310. {
  3311. "data": {
  3312. "text/plain": [
  3313. "array([ 0.80070487, 0.45527067, 0.87010206])"
  3314. ]
  3315. },
  3316. "execution_count": 130,
  3317. "metadata": {},
  3318. "output_type": "execute_result"
  3319. }
  3320. ],
  3321. "source": [
  3322. "# max in each column\n",
  3323. "m.max(axis=0)"
  3324. ]
  3325. },
  3326. {
  3327. "cell_type": "code",
  3328. "execution_count": 131,
  3329. "metadata": {},
  3330. "outputs": [
  3331. {
  3332. "data": {
  3333. "text/plain": [
  3334. "array([ 0.2850926 , 0.80070487, 0.87010206])"
  3335. ]
  3336. },
  3337. "execution_count": 131,
  3338. "metadata": {},
  3339. "output_type": "execute_result"
  3340. }
  3341. ],
  3342. "source": [
  3343. "# max in each row\n",
  3344. "m.max(axis=1)"
  3345. ]
  3346. },
  3347. {
  3348. "cell_type": "markdown",
  3349. "metadata": {},
  3350. "source": [
  3351. "Many other functions and methods in the `array` and `matrix` classes accept the same (optional) `axis` keyword argument."
  3352. ]
  3353. },
  3354. {
  3355. "cell_type": "markdown",
  3356. "metadata": {},
  3357. "source": [
  3358. "## Reshaping, resizing and stacking arrays"
  3359. ]
  3360. },
  3361. {
  3362. "cell_type": "markdown",
  3363. "metadata": {},
  3364. "source": [
  3365. "The shape of an Numpy array can be modified without copying the underlaying data, which makes it a fast operation even for large arrays."
  3366. ]
  3367. },
  3368. {
  3369. "cell_type": "code",
  3370. "execution_count": 132,
  3371. "metadata": {},
  3372. "outputs": [
  3373. {
  3374. "data": {
  3375. "text/plain": [
  3376. "array([[ 0, 1, 2, 3, 4],\n",
  3377. " [10, 11, 12, 13, 14],\n",
  3378. " [20, 21, 22, 23, 24],\n",
  3379. " [30, 31, 32, 33, 34],\n",
  3380. " [40, 41, 42, 43, 44]])"
  3381. ]
  3382. },
  3383. "execution_count": 132,
  3384. "metadata": {},
  3385. "output_type": "execute_result"
  3386. }
  3387. ],
  3388. "source": [
  3389. "A"
  3390. ]
  3391. },
  3392. {
  3393. "cell_type": "code",
  3394. "execution_count": 133,
  3395. "metadata": {},
  3396. "outputs": [],
  3397. "source": [
  3398. "n, m = A.shape"
  3399. ]
  3400. },
  3401. {
  3402. "cell_type": "code",
  3403. "execution_count": 134,
  3404. "metadata": {},
  3405. "outputs": [
  3406. {
  3407. "data": {
  3408. "text/plain": [
  3409. "array([[ 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31,\n",
  3410. " 32, 33, 34, 40, 41, 42, 43, 44]])"
  3411. ]
  3412. },
  3413. "execution_count": 134,
  3414. "metadata": {},
  3415. "output_type": "execute_result"
  3416. }
  3417. ],
  3418. "source": [
  3419. "B = A.reshape((1,n*m))\n",
  3420. "B"
  3421. ]
  3422. },
  3423. {
  3424. "cell_type": "code",
  3425. "execution_count": 135,
  3426. "metadata": {},
  3427. "outputs": [
  3428. {
  3429. "data": {
  3430. "text/plain": [
  3431. "array([[ 5, 5, 5, 5, 5, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31,\n",
  3432. " 32, 33, 34, 40, 41, 42, 43, 44]])"
  3433. ]
  3434. },
  3435. "execution_count": 135,
  3436. "metadata": {},
  3437. "output_type": "execute_result"
  3438. }
  3439. ],
  3440. "source": [
  3441. "B[0,0:5] = 5 # modify the array\n",
  3442. "\n",
  3443. "B"
  3444. ]
  3445. },
  3446. {
  3447. "cell_type": "code",
  3448. "execution_count": 136,
  3449. "metadata": {},
  3450. "outputs": [
  3451. {
  3452. "data": {
  3453. "text/plain": [
  3454. "array([[ 5, 5, 5, 5, 5],\n",
  3455. " [10, 11, 12, 13, 14],\n",
  3456. " [20, 21, 22, 23, 24],\n",
  3457. " [30, 31, 32, 33, 34],\n",
  3458. " [40, 41, 42, 43, 44]])"
  3459. ]
  3460. },
  3461. "execution_count": 136,
  3462. "metadata": {},
  3463. "output_type": "execute_result"
  3464. }
  3465. ],
  3466. "source": [
  3467. "A # and the original variable is also changed. B is only a different view of the same data"
  3468. ]
  3469. },
  3470. {
  3471. "cell_type": "markdown",
  3472. "metadata": {},
  3473. "source": [
  3474. "We can also use the function `flatten` to make a higher-dimensional array into a vector. But this function create a copy of the data."
  3475. ]
  3476. },
  3477. {
  3478. "cell_type": "code",
  3479. "execution_count": 137,
  3480. "metadata": {},
  3481. "outputs": [
  3482. {
  3483. "data": {
  3484. "text/plain": [
  3485. "array([ 5, 5, 5, 5, 5, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31,\n",
  3486. " 32, 33, 34, 40, 41, 42, 43, 44])"
  3487. ]
  3488. },
  3489. "execution_count": 137,
  3490. "metadata": {},
  3491. "output_type": "execute_result"
  3492. }
  3493. ],
  3494. "source": [
  3495. "B = A.flatten()\n",
  3496. "\n",
  3497. "B"
  3498. ]
  3499. },
  3500. {
  3501. "cell_type": "code",
  3502. "execution_count": 138,
  3503. "metadata": {},
  3504. "outputs": [
  3505. {
  3506. "data": {
  3507. "text/plain": [
  3508. "array([10, 10, 10, 10, 10, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31,\n",
  3509. " 32, 33, 34, 40, 41, 42, 43, 44])"
  3510. ]
  3511. },
  3512. "execution_count": 138,
  3513. "metadata": {},
  3514. "output_type": "execute_result"
  3515. }
  3516. ],
  3517. "source": [
  3518. "B[0:5] = 10\n",
  3519. "\n",
  3520. "B"
  3521. ]
  3522. },
  3523. {
  3524. "cell_type": "code",
  3525. "execution_count": 139,
  3526. "metadata": {},
  3527. "outputs": [
  3528. {
  3529. "data": {
  3530. "text/plain": [
  3531. "array([[ 5, 5, 5, 5, 5],\n",
  3532. " [10, 11, 12, 13, 14],\n",
  3533. " [20, 21, 22, 23, 24],\n",
  3534. " [30, 31, 32, 33, 34],\n",
  3535. " [40, 41, 42, 43, 44]])"
  3536. ]
  3537. },
  3538. "execution_count": 139,
  3539. "metadata": {},
  3540. "output_type": "execute_result"
  3541. }
  3542. ],
  3543. "source": [
  3544. "A # now A has not changed, because B's data is a copy of A's, not refering to the same data"
  3545. ]
  3546. },
  3547. {
  3548. "cell_type": "markdown",
  3549. "metadata": {},
  3550. "source": [
  3551. "## Adding a new dimension: newaxis"
  3552. ]
  3553. },
  3554. {
  3555. "cell_type": "markdown",
  3556. "metadata": {},
  3557. "source": [
  3558. "With `newaxis`, we can insert new dimensions in an array, for example converting a vector to a column or row matrix:"
  3559. ]
  3560. },
  3561. {
  3562. "cell_type": "code",
  3563. "execution_count": 140,
  3564. "metadata": {},
  3565. "outputs": [],
  3566. "source": [
  3567. "v = array([1,2,3])"
  3568. ]
  3569. },
  3570. {
  3571. "cell_type": "code",
  3572. "execution_count": 141,
  3573. "metadata": {},
  3574. "outputs": [
  3575. {
  3576. "data": {
  3577. "text/plain": [
  3578. "(3,)"
  3579. ]
  3580. },
  3581. "execution_count": 141,
  3582. "metadata": {},
  3583. "output_type": "execute_result"
  3584. }
  3585. ],
  3586. "source": [
  3587. "shape(v)"
  3588. ]
  3589. },
  3590. {
  3591. "cell_type": "code",
  3592. "execution_count": 142,
  3593. "metadata": {},
  3594. "outputs": [
  3595. {
  3596. "data": {
  3597. "text/plain": [
  3598. "array([[1],\n",
  3599. " [2],\n",
  3600. " [3]])"
  3601. ]
  3602. },
  3603. "execution_count": 142,
  3604. "metadata": {},
  3605. "output_type": "execute_result"
  3606. }
  3607. ],
  3608. "source": [
  3609. "# make a column matrix of the vector v\n",
  3610. "v[:, newaxis]"
  3611. ]
  3612. },
  3613. {
  3614. "cell_type": "code",
  3615. "execution_count": 143,
  3616. "metadata": {},
  3617. "outputs": [
  3618. {
  3619. "data": {
  3620. "text/plain": [
  3621. "(3, 1)"
  3622. ]
  3623. },
  3624. "execution_count": 143,
  3625. "metadata": {},
  3626. "output_type": "execute_result"
  3627. }
  3628. ],
  3629. "source": [
  3630. "# column matrix\n",
  3631. "v[:,newaxis].shape"
  3632. ]
  3633. },
  3634. {
  3635. "cell_type": "code",
  3636. "execution_count": 144,
  3637. "metadata": {},
  3638. "outputs": [
  3639. {
  3640. "data": {
  3641. "text/plain": [
  3642. "(1, 3)"
  3643. ]
  3644. },
  3645. "execution_count": 144,
  3646. "metadata": {},
  3647. "output_type": "execute_result"
  3648. }
  3649. ],
  3650. "source": [
  3651. "# row matrix\n",
  3652. "v[newaxis,:].shape"
  3653. ]
  3654. },
  3655. {
  3656. "cell_type": "markdown",
  3657. "metadata": {},
  3658. "source": [
  3659. "## Stacking and repeating arrays"
  3660. ]
  3661. },
  3662. {
  3663. "cell_type": "markdown",
  3664. "metadata": {},
  3665. "source": [
  3666. "Using function `repeat`, `tile`, `vstack`, `hstack`, and `concatenate` we can create larger vectors and matrices from smaller ones:"
  3667. ]
  3668. },
  3669. {
  3670. "cell_type": "markdown",
  3671. "metadata": {},
  3672. "source": [
  3673. "### tile and repeat"
  3674. ]
  3675. },
  3676. {
  3677. "cell_type": "code",
  3678. "execution_count": 145,
  3679. "metadata": {},
  3680. "outputs": [],
  3681. "source": [
  3682. "a = array([[1, 2], [3, 4]])"
  3683. ]
  3684. },
  3685. {
  3686. "cell_type": "code",
  3687. "execution_count": 146,
  3688. "metadata": {},
  3689. "outputs": [
  3690. {
  3691. "data": {
  3692. "text/plain": [
  3693. "array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])"
  3694. ]
  3695. },
  3696. "execution_count": 146,
  3697. "metadata": {},
  3698. "output_type": "execute_result"
  3699. }
  3700. ],
  3701. "source": [
  3702. "# repeat each element 3 times\n",
  3703. "repeat(a, 3)"
  3704. ]
  3705. },
  3706. {
  3707. "cell_type": "code",
  3708. "execution_count": 147,
  3709. "metadata": {},
  3710. "outputs": [
  3711. {
  3712. "data": {
  3713. "text/plain": [
  3714. "array([[1, 2, 1, 2, 1, 2],\n",
  3715. " [3, 4, 3, 4, 3, 4]])"
  3716. ]
  3717. },
  3718. "execution_count": 147,
  3719. "metadata": {},
  3720. "output_type": "execute_result"
  3721. }
  3722. ],
  3723. "source": [
  3724. "# tile the matrix 3 times \n",
  3725. "tile(a, 3)"
  3726. ]
  3727. },
  3728. {
  3729. "cell_type": "markdown",
  3730. "metadata": {},
  3731. "source": [
  3732. "### concatenate"
  3733. ]
  3734. },
  3735. {
  3736. "cell_type": "code",
  3737. "execution_count": 148,
  3738. "metadata": {},
  3739. "outputs": [],
  3740. "source": [
  3741. "b = array([[5, 6]])"
  3742. ]
  3743. },
  3744. {
  3745. "cell_type": "code",
  3746. "execution_count": 149,
  3747. "metadata": {},
  3748. "outputs": [
  3749. {
  3750. "data": {
  3751. "text/plain": [
  3752. "array([[1, 2],\n",
  3753. " [3, 4],\n",
  3754. " [5, 6]])"
  3755. ]
  3756. },
  3757. "execution_count": 149,
  3758. "metadata": {},
  3759. "output_type": "execute_result"
  3760. }
  3761. ],
  3762. "source": [
  3763. "concatenate((a, b), axis=0)"
  3764. ]
  3765. },
  3766. {
  3767. "cell_type": "code",
  3768. "execution_count": 150,
  3769. "metadata": {},
  3770. "outputs": [
  3771. {
  3772. "data": {
  3773. "text/plain": [
  3774. "array([[1, 2, 5],\n",
  3775. " [3, 4, 6]])"
  3776. ]
  3777. },
  3778. "execution_count": 150,
  3779. "metadata": {},
  3780. "output_type": "execute_result"
  3781. }
  3782. ],
  3783. "source": [
  3784. "concatenate((a, b.T), axis=1)"
  3785. ]
  3786. },
  3787. {
  3788. "cell_type": "markdown",
  3789. "metadata": {},
  3790. "source": [
  3791. "### hstack and vstack"
  3792. ]
  3793. },
  3794. {
  3795. "cell_type": "code",
  3796. "execution_count": 151,
  3797. "metadata": {},
  3798. "outputs": [
  3799. {
  3800. "data": {
  3801. "text/plain": [
  3802. "array([[1, 2],\n",
  3803. " [3, 4],\n",
  3804. " [5, 6]])"
  3805. ]
  3806. },
  3807. "execution_count": 151,
  3808. "metadata": {},
  3809. "output_type": "execute_result"
  3810. }
  3811. ],
  3812. "source": [
  3813. "vstack((a,b))"
  3814. ]
  3815. },
  3816. {
  3817. "cell_type": "code",
  3818. "execution_count": 152,
  3819. "metadata": {},
  3820. "outputs": [
  3821. {
  3822. "data": {
  3823. "text/plain": [
  3824. "array([[1, 2, 5],\n",
  3825. " [3, 4, 6]])"
  3826. ]
  3827. },
  3828. "execution_count": 152,
  3829. "metadata": {},
  3830. "output_type": "execute_result"
  3831. }
  3832. ],
  3833. "source": [
  3834. "hstack((a,b.T))"
  3835. ]
  3836. },
  3837. {
  3838. "cell_type": "markdown",
  3839. "metadata": {},
  3840. "source": [
  3841. "## Copy and \"deep copy\""
  3842. ]
  3843. },
  3844. {
  3845. "cell_type": "markdown",
  3846. "metadata": {},
  3847. "source": [
  3848. "To achieve high performance, assignments in Python usually do not copy the underlaying objects. This is important for example when objects are passed between functions, to avoid an excessive amount of memory copying when it is not necessary (technical term: pass by reference). "
  3849. ]
  3850. },
  3851. {
  3852. "cell_type": "code",
  3853. "execution_count": 153,
  3854. "metadata": {},
  3855. "outputs": [
  3856. {
  3857. "data": {
  3858. "text/plain": [
  3859. "array([[1, 2],\n",
  3860. " [3, 4]])"
  3861. ]
  3862. },
  3863. "execution_count": 153,
  3864. "metadata": {},
  3865. "output_type": "execute_result"
  3866. }
  3867. ],
  3868. "source": [
  3869. "A = array([[1, 2], [3, 4]])\n",
  3870. "\n",
  3871. "A"
  3872. ]
  3873. },
  3874. {
  3875. "cell_type": "code",
  3876. "execution_count": 154,
  3877. "metadata": {},
  3878. "outputs": [],
  3879. "source": [
  3880. "# now B is referring to the same array data as A \n",
  3881. "B = A "
  3882. ]
  3883. },
  3884. {
  3885. "cell_type": "code",
  3886. "execution_count": 155,
  3887. "metadata": {},
  3888. "outputs": [
  3889. {
  3890. "data": {
  3891. "text/plain": [
  3892. "array([[10, 2],\n",
  3893. " [ 3, 4]])"
  3894. ]
  3895. },
  3896. "execution_count": 155,
  3897. "metadata": {},
  3898. "output_type": "execute_result"
  3899. }
  3900. ],
  3901. "source": [
  3902. "# changing B affects A\n",
  3903. "B[0,0] = 10\n",
  3904. "\n",
  3905. "B"
  3906. ]
  3907. },
  3908. {
  3909. "cell_type": "code",
  3910. "execution_count": 156,
  3911. "metadata": {},
  3912. "outputs": [
  3913. {
  3914. "data": {
  3915. "text/plain": [
  3916. "array([[10, 2],\n",
  3917. " [ 3, 4]])"
  3918. ]
  3919. },
  3920. "execution_count": 156,
  3921. "metadata": {},
  3922. "output_type": "execute_result"
  3923. }
  3924. ],
  3925. "source": [
  3926. "A"
  3927. ]
  3928. },
  3929. {
  3930. "cell_type": "markdown",
  3931. "metadata": {},
  3932. "source": [
  3933. "If we want to avoid this behavior, so that when we get a new completely independent object `B` copied from `A`, then we need to do a so-called \"deep copy\" using the function `copy`:"
  3934. ]
  3935. },
  3936. {
  3937. "cell_type": "code",
  3938. "execution_count": 157,
  3939. "metadata": {},
  3940. "outputs": [],
  3941. "source": [
  3942. "B = copy(A)"
  3943. ]
  3944. },
  3945. {
  3946. "cell_type": "code",
  3947. "execution_count": 158,
  3948. "metadata": {},
  3949. "outputs": [
  3950. {
  3951. "data": {
  3952. "text/plain": [
  3953. "array([[-5, 2],\n",
  3954. " [ 3, 4]])"
  3955. ]
  3956. },
  3957. "execution_count": 158,
  3958. "metadata": {},
  3959. "output_type": "execute_result"
  3960. }
  3961. ],
  3962. "source": [
  3963. "# now, if we modify B, A is not affected\n",
  3964. "B[0,0] = -5\n",
  3965. "\n",
  3966. "B"
  3967. ]
  3968. },
  3969. {
  3970. "cell_type": "code",
  3971. "execution_count": 159,
  3972. "metadata": {},
  3973. "outputs": [
  3974. {
  3975. "data": {
  3976. "text/plain": [
  3977. "array([[10, 2],\n",
  3978. " [ 3, 4]])"
  3979. ]
  3980. },
  3981. "execution_count": 159,
  3982. "metadata": {},
  3983. "output_type": "execute_result"
  3984. }
  3985. ],
  3986. "source": [
  3987. "A"
  3988. ]
  3989. },
  3990. {
  3991. "cell_type": "markdown",
  3992. "metadata": {},
  3993. "source": [
  3994. "## Iterating over array elements"
  3995. ]
  3996. },
  3997. {
  3998. "cell_type": "markdown",
  3999. "metadata": {},
  4000. "source": [
  4001. "Generally, we want to avoid iterating over the elements of arrays whenever we can (at all costs). The reason is that in a interpreted language like Python (or MATLAB), iterations are really slow compared to vectorized operations. \n",
  4002. "\n",
  4003. "However, sometimes iterations are unavoidable. For such cases, the Python `for` loop is the most convenient way to iterate over an array:"
  4004. ]
  4005. },
  4006. {
  4007. "cell_type": "code",
  4008. "execution_count": 160,
  4009. "metadata": {},
  4010. "outputs": [
  4011. {
  4012. "name": "stdout",
  4013. "output_type": "stream",
  4014. "text": [
  4015. "1\n",
  4016. "2\n",
  4017. "3\n",
  4018. "4\n"
  4019. ]
  4020. }
  4021. ],
  4022. "source": [
  4023. "v = array([1,2,3,4])\n",
  4024. "\n",
  4025. "for element in v:\n",
  4026. " print(element)"
  4027. ]
  4028. },
  4029. {
  4030. "cell_type": "code",
  4031. "execution_count": 161,
  4032. "metadata": {},
  4033. "outputs": [
  4034. {
  4035. "name": "stdout",
  4036. "output_type": "stream",
  4037. "text": [
  4038. "('row', array([1, 2]))\n",
  4039. "1\n",
  4040. "2\n",
  4041. "('row', array([3, 4]))\n",
  4042. "3\n",
  4043. "4\n"
  4044. ]
  4045. }
  4046. ],
  4047. "source": [
  4048. "M = array([[1,2], [3,4]])\n",
  4049. "\n",
  4050. "for row in M:\n",
  4051. " print(\"row\", row)\n",
  4052. " \n",
  4053. " for element in row:\n",
  4054. " print(element)"
  4055. ]
  4056. },
  4057. {
  4058. "cell_type": "markdown",
  4059. "metadata": {},
  4060. "source": [
  4061. "When we need to iterate over each element of an array and modify its elements, it is convenient to use the `enumerate` function to obtain both the element and its index in the `for` loop: "
  4062. ]
  4063. },
  4064. {
  4065. "cell_type": "code",
  4066. "execution_count": 162,
  4067. "metadata": {},
  4068. "outputs": [
  4069. {
  4070. "name": "stdout",
  4071. "output_type": "stream",
  4072. "text": [
  4073. "('row_idx', 0, 'row', array([1, 2]))\n",
  4074. "('col_idx', 0, 'element', 1)\n",
  4075. "('col_idx', 1, 'element', 2)\n",
  4076. "('row_idx', 1, 'row', array([3, 4]))\n",
  4077. "('col_idx', 0, 'element', 3)\n",
  4078. "('col_idx', 1, 'element', 4)\n"
  4079. ]
  4080. }
  4081. ],
  4082. "source": [
  4083. "for row_idx, row in enumerate(M):\n",
  4084. " print(\"row_idx\", row_idx, \"row\", row)\n",
  4085. " \n",
  4086. " for col_idx, element in enumerate(row):\n",
  4087. " print(\"col_idx\", col_idx, \"element\", element)\n",
  4088. " \n",
  4089. " # update the matrix M: square each element\n",
  4090. " M[row_idx, col_idx] = element ** 2"
  4091. ]
  4092. },
  4093. {
  4094. "cell_type": "code",
  4095. "execution_count": 163,
  4096. "metadata": {},
  4097. "outputs": [
  4098. {
  4099. "data": {
  4100. "text/plain": [
  4101. "array([[ 1, 4],\n",
  4102. " [ 9, 16]])"
  4103. ]
  4104. },
  4105. "execution_count": 163,
  4106. "metadata": {},
  4107. "output_type": "execute_result"
  4108. }
  4109. ],
  4110. "source": [
  4111. "# each element in M is now squared\n",
  4112. "M"
  4113. ]
  4114. },
  4115. {
  4116. "cell_type": "markdown",
  4117. "metadata": {},
  4118. "source": [
  4119. "## Vectorizing functions"
  4120. ]
  4121. },
  4122. {
  4123. "cell_type": "markdown",
  4124. "metadata": {},
  4125. "source": [
  4126. "As mentioned several times by now, to get good performance we should try to avoid looping over elements in our vectors and matrices, and instead use vectorized algorithms. The first step in converting a scalar algorithm to a vectorized algorithm is to make sure that the functions we write work with vector inputs."
  4127. ]
  4128. },
  4129. {
  4130. "cell_type": "code",
  4131. "execution_count": 164,
  4132. "metadata": {},
  4133. "outputs": [],
  4134. "source": [
  4135. "def Theta(x):\n",
  4136. " \"\"\"\n",
  4137. " Scalar implemenation of the Heaviside step function.\n",
  4138. " \"\"\"\n",
  4139. " if x >= 0:\n",
  4140. " return 1\n",
  4141. " else:\n",
  4142. " return 0"
  4143. ]
  4144. },
  4145. {
  4146. "cell_type": "code",
  4147. "execution_count": 165,
  4148. "metadata": {},
  4149. "outputs": [
  4150. {
  4151. "ename": "ValueError",
  4152. "evalue": "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()",
  4153. "output_type": "error",
  4154. "traceback": [
  4155. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  4156. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  4157. "\u001b[0;32m<ipython-input-165-6658efdd2f22>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mTheta\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
  4158. "\u001b[0;32m<ipython-input-164-9a0cb13d93d4>\u001b[0m in \u001b[0;36mTheta\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mScalar\u001b[0m \u001b[0mimplemenation\u001b[0m \u001b[0mof\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mHeaviside\u001b[0m \u001b[0mstep\u001b[0m \u001b[0mfunction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \"\"\"\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
  4159. "\u001b[0;31mValueError\u001b[0m: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"
  4160. ]
  4161. }
  4162. ],
  4163. "source": [
  4164. "Theta(array([-3,-2,-1,0,1,2,3]))"
  4165. ]
  4166. },
  4167. {
  4168. "cell_type": "markdown",
  4169. "metadata": {},
  4170. "source": [
  4171. "OK, that didn't work because we didn't write the `Theta` function so that it can handle a vector input... \n",
  4172. "\n",
  4173. "To get a vectorized version of Theta we can use the Numpy function `vectorize`. In many cases it can automatically vectorize a function:"
  4174. ]
  4175. },
  4176. {
  4177. "cell_type": "code",
  4178. "execution_count": 166,
  4179. "metadata": {},
  4180. "outputs": [],
  4181. "source": [
  4182. "Theta_vec = vectorize(Theta)"
  4183. ]
  4184. },
  4185. {
  4186. "cell_type": "code",
  4187. "execution_count": 167,
  4188. "metadata": {},
  4189. "outputs": [
  4190. {
  4191. "data": {
  4192. "text/plain": [
  4193. "array([0, 0, 0, 1, 1, 1, 1])"
  4194. ]
  4195. },
  4196. "execution_count": 167,
  4197. "metadata": {},
  4198. "output_type": "execute_result"
  4199. }
  4200. ],
  4201. "source": [
  4202. "Theta_vec(array([-3,-2,-1,0,1,2,3]))"
  4203. ]
  4204. },
  4205. {
  4206. "cell_type": "markdown",
  4207. "metadata": {},
  4208. "source": [
  4209. "We can also implement the function to accept a vector input from the beginning (requires more effort but might give better performance):"
  4210. ]
  4211. },
  4212. {
  4213. "cell_type": "code",
  4214. "execution_count": 168,
  4215. "metadata": {},
  4216. "outputs": [],
  4217. "source": [
  4218. "def Theta(x):\n",
  4219. " \"\"\"\n",
  4220. " Vector-aware implemenation of the Heaviside step function.\n",
  4221. " \"\"\"\n",
  4222. " return 1 * (x >= 0)"
  4223. ]
  4224. },
  4225. {
  4226. "cell_type": "code",
  4227. "execution_count": 169,
  4228. "metadata": {},
  4229. "outputs": [
  4230. {
  4231. "data": {
  4232. "text/plain": [
  4233. "array([0, 0, 0, 1, 1, 1, 1])"
  4234. ]
  4235. },
  4236. "execution_count": 169,
  4237. "metadata": {},
  4238. "output_type": "execute_result"
  4239. }
  4240. ],
  4241. "source": [
  4242. "Theta(array([-3,-2,-1,0,1,2,3]))"
  4243. ]
  4244. },
  4245. {
  4246. "cell_type": "code",
  4247. "execution_count": 170,
  4248. "metadata": {},
  4249. "outputs": [
  4250. {
  4251. "data": {
  4252. "text/plain": [
  4253. "(0, 1)"
  4254. ]
  4255. },
  4256. "execution_count": 170,
  4257. "metadata": {},
  4258. "output_type": "execute_result"
  4259. }
  4260. ],
  4261. "source": [
  4262. "# still works for scalars as well\n",
  4263. "Theta(-1.2), Theta(2.6)"
  4264. ]
  4265. },
  4266. {
  4267. "cell_type": "markdown",
  4268. "metadata": {},
  4269. "source": [
  4270. "## Using arrays in conditions"
  4271. ]
  4272. },
  4273. {
  4274. "cell_type": "markdown",
  4275. "metadata": {},
  4276. "source": [
  4277. "When using arrays in conditions,for example `if` statements and other boolean expressions, one needs to use `any` or `all`, which requires that any or all elements in the array evalutes to `True`:"
  4278. ]
  4279. },
  4280. {
  4281. "cell_type": "code",
  4282. "execution_count": 171,
  4283. "metadata": {},
  4284. "outputs": [
  4285. {
  4286. "data": {
  4287. "text/plain": [
  4288. "array([[ 1, 4],\n",
  4289. " [ 9, 16]])"
  4290. ]
  4291. },
  4292. "execution_count": 171,
  4293. "metadata": {},
  4294. "output_type": "execute_result"
  4295. }
  4296. ],
  4297. "source": [
  4298. "M"
  4299. ]
  4300. },
  4301. {
  4302. "cell_type": "code",
  4303. "execution_count": 172,
  4304. "metadata": {},
  4305. "outputs": [
  4306. {
  4307. "name": "stdout",
  4308. "output_type": "stream",
  4309. "text": [
  4310. "at least one element in M is larger than 5\n"
  4311. ]
  4312. }
  4313. ],
  4314. "source": [
  4315. "if (M > 5).any():\n",
  4316. " print(\"at least one element in M is larger than 5\")\n",
  4317. "else:\n",
  4318. " print(\"no element in M is larger than 5\")"
  4319. ]
  4320. },
  4321. {
  4322. "cell_type": "code",
  4323. "execution_count": 173,
  4324. "metadata": {},
  4325. "outputs": [
  4326. {
  4327. "name": "stdout",
  4328. "output_type": "stream",
  4329. "text": [
  4330. "all elements in M are not larger than 5\n"
  4331. ]
  4332. }
  4333. ],
  4334. "source": [
  4335. "if (M > 5).all():\n",
  4336. " print(\"all elements in M are larger than 5\")\n",
  4337. "else:\n",
  4338. " print(\"all elements in M are not larger than 5\")"
  4339. ]
  4340. },
  4341. {
  4342. "cell_type": "markdown",
  4343. "metadata": {},
  4344. "source": [
  4345. "## Type casting"
  4346. ]
  4347. },
  4348. {
  4349. "cell_type": "markdown",
  4350. "metadata": {},
  4351. "source": [
  4352. "Since Numpy arrays are *statically typed*, the type of an array does not change once created. But we can explicitly cast an array of some type to another using the `astype` functions (see also the similar `asarray` function). This always create a new array of new type:"
  4353. ]
  4354. },
  4355. {
  4356. "cell_type": "code",
  4357. "execution_count": 174,
  4358. "metadata": {},
  4359. "outputs": [
  4360. {
  4361. "data": {
  4362. "text/plain": [
  4363. "dtype('int64')"
  4364. ]
  4365. },
  4366. "execution_count": 174,
  4367. "metadata": {},
  4368. "output_type": "execute_result"
  4369. }
  4370. ],
  4371. "source": [
  4372. "M.dtype"
  4373. ]
  4374. },
  4375. {
  4376. "cell_type": "code",
  4377. "execution_count": 175,
  4378. "metadata": {},
  4379. "outputs": [
  4380. {
  4381. "data": {
  4382. "text/plain": [
  4383. "array([[ 1., 4.],\n",
  4384. " [ 9., 16.]])"
  4385. ]
  4386. },
  4387. "execution_count": 175,
  4388. "metadata": {},
  4389. "output_type": "execute_result"
  4390. }
  4391. ],
  4392. "source": [
  4393. "M2 = M.astype(float)\n",
  4394. "\n",
  4395. "M2"
  4396. ]
  4397. },
  4398. {
  4399. "cell_type": "code",
  4400. "execution_count": 176,
  4401. "metadata": {},
  4402. "outputs": [
  4403. {
  4404. "data": {
  4405. "text/plain": [
  4406. "dtype('float64')"
  4407. ]
  4408. },
  4409. "execution_count": 176,
  4410. "metadata": {},
  4411. "output_type": "execute_result"
  4412. }
  4413. ],
  4414. "source": [
  4415. "M2.dtype"
  4416. ]
  4417. },
  4418. {
  4419. "cell_type": "code",
  4420. "execution_count": 177,
  4421. "metadata": {},
  4422. "outputs": [
  4423. {
  4424. "data": {
  4425. "text/plain": [
  4426. "array([[ True, True],\n",
  4427. " [ True, True]], dtype=bool)"
  4428. ]
  4429. },
  4430. "execution_count": 177,
  4431. "metadata": {},
  4432. "output_type": "execute_result"
  4433. }
  4434. ],
  4435. "source": [
  4436. "M3 = M.astype(bool)\n",
  4437. "\n",
  4438. "M3"
  4439. ]
  4440. },
  4441. {
  4442. "cell_type": "markdown",
  4443. "metadata": {},
  4444. "source": [
  4445. "## Further reading"
  4446. ]
  4447. },
  4448. {
  4449. "cell_type": "markdown",
  4450. "metadata": {},
  4451. "source": [
  4452. "* http://numpy.scipy.org\n",
  4453. "* http://scipy.org/Tentative_NumPy_Tutorial\n",
  4454. "* http://scipy.org/NumPy_for_Matlab_Users - A Numpy guide for MATLAB users."
  4455. ]
  4456. },
  4457. {
  4458. "cell_type": "markdown",
  4459. "metadata": {},
  4460. "source": [
  4461. "## Versions"
  4462. ]
  4463. },
  4464. {
  4465. "cell_type": "code",
  4466. "execution_count": 178,
  4467. "metadata": {},
  4468. "outputs": [
  4469. {
  4470. "data": {
  4471. "application/json": {
  4472. "Software versions": [
  4473. {
  4474. "module": "Python",
  4475. "version": "2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]"
  4476. },
  4477. {
  4478. "module": "IPython",
  4479. "version": "3.2.1"
  4480. },
  4481. {
  4482. "module": "OS",
  4483. "version": "Darwin 14.1.0 x86_64 i386 64bit"
  4484. },
  4485. {
  4486. "module": "numpy",
  4487. "version": "1.9.2"
  4488. }
  4489. ]
  4490. },
  4491. "text/html": [
  4492. "<table><tr><th>Software</th><th>Version</th></tr><tr><td>Python</td><td>2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]</td></tr><tr><td>IPython</td><td>3.2.1</td></tr><tr><td>OS</td><td>Darwin 14.1.0 x86_64 i386 64bit</td></tr><tr><td>numpy</td><td>1.9.2</td></tr><tr><td colspan='2'>Sat Aug 15 11:02:09 2015 JST</td></tr></table>"
  4493. ],
  4494. "text/latex": [
  4495. "\\begin{tabular}{|l|l|}\\hline\n",
  4496. "{\\bf Software} & {\\bf Version} \\\\ \\hline\\hline\n",
  4497. "Python & 2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)] \\\\ \\hline\n",
  4498. "IPython & 3.2.1 \\\\ \\hline\n",
  4499. "OS & Darwin 14.1.0 x86\\_64 i386 64bit \\\\ \\hline\n",
  4500. "numpy & 1.9.2 \\\\ \\hline\n",
  4501. "\\hline \\multicolumn{2}{|l|}{Sat Aug 15 11:02:09 2015 JST} \\\\ \\hline\n",
  4502. "\\end{tabular}\n"
  4503. ],
  4504. "text/plain": [
  4505. "Software versions\n",
  4506. "Python 2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]\n",
  4507. "IPython 3.2.1\n",
  4508. "OS Darwin 14.1.0 x86_64 i386 64bit\n",
  4509. "numpy 1.9.2\n",
  4510. "Sat Aug 15 11:02:09 2015 JST"
  4511. ]
  4512. },
  4513. "execution_count": 178,
  4514. "metadata": {},
  4515. "output_type": "execute_result"
  4516. }
  4517. ],
  4518. "source": [
  4519. "%reload_ext version_information\n",
  4520. "\n",
  4521. "%version_information numpy"
  4522. ]
  4523. }
  4524. ],
  4525. "metadata": {
  4526. "kernelspec": {
  4527. "display_name": "Python 3",
  4528. "language": "python",
  4529. "name": "python3"
  4530. },
  4531. "language_info": {
  4532. "codemirror_mode": {
  4533. "name": "ipython",
  4534. "version": 3
  4535. },
  4536. "file_extension": ".py",
  4537. "mimetype": "text/x-python",
  4538. "name": "python",
  4539. "nbconvert_exporter": "python",
  4540. "pygments_lexer": "ipython3",
  4541. "version": "3.5.2"
  4542. }
  4543. },
  4544. "nbformat": 4,
  4545. "nbformat_minor": 1
  4546. }

机器学习越来越多应用到飞行器、机器人等领域,其目的是利用计算机实现类似人类的智能,从而实现装备的智能化与无人化。本课程旨在引导学生掌握机器学习的基本知识、典型方法与技术,通过具体的应用案例激发学生对该学科的兴趣,鼓励学生能够从人工智能的角度来分析、解决飞行器、机器人所面临的问题和挑战。本课程主要内容包括Python编程基础,机器学习模型,无监督学习、监督学习、深度学习基础知识与实现,并学习如何利用机器学习解决实际问题,从而全面提升自我的《综合能力》。