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.

1-numpy_tutorial.ipynb 164 kB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "markdown",
  5. "metadata": {},
  6. "source": [
  7. "# Numpy - 多维数据的数组"
  8. ]
  9. },
  10. {
  11. "cell_type": "markdown",
  12. "metadata": {},
  13. "source": [
  14. "J.R. Johansson (jrjohansson at gmail.com)\n",
  15. "\n",
  16. "最新的[IPython notebook](http://ipython.org/notebook.html)课程可以在[http://github.com/jrjohansson/scientific-python-lectures](http://github.com/jrjohansson/scientific-python-lectures) 找到.\n",
  17. "\n",
  18. "其他有关这个课程的参考书在这里标注出[http://jrjohansson.github.io](http://jrjohansson.github.io).\n"
  19. ]
  20. },
  21. {
  22. "cell_type": "code",
  23. "execution_count": 1,
  24. "metadata": {},
  25. "outputs": [],
  26. "source": [
  27. "# 这一行的作用会在课程4中回答\n",
  28. "%matplotlib inline\n",
  29. "import matplotlib.pyplot as plt"
  30. ]
  31. },
  32. {
  33. "cell_type": "markdown",
  34. "metadata": {},
  35. "source": [
  36. "## 简介"
  37. ]
  38. },
  39. {
  40. "cell_type": "markdown",
  41. "metadata": {},
  42. "source": [
  43. "这个`numpy`包(模块)用在几乎所有使用Python的数值计算中。他是一个为Python提供高性能向量,矩阵和高维数据结构的模块。它是用C和Fortran语言实现的,因此当计算被向量化(用向量和矩阵表示)时,性能非常的好。\n",
  44. "\n",
  45. "为了使用`numpy`模块,你先要向下面的例子一样导入这个模块:"
  46. ]
  47. },
  48. {
  49. "cell_type": "code",
  50. "execution_count": 2,
  51. "metadata": {},
  52. "outputs": [],
  53. "source": [
  54. "from numpy import *\n",
  55. "import numpy as np"
  56. ]
  57. },
  58. {
  59. "cell_type": "markdown",
  60. "metadata": {},
  61. "source": [
  62. "在`numpy`模块中,用于向量,矩阵和高维数据集的术语是*数组*。\n",
  63. "\n"
  64. ]
  65. },
  66. {
  67. "cell_type": "markdown",
  68. "metadata": {},
  69. "source": [
  70. "## 创建`numpy`数组"
  71. ]
  72. },
  73. {
  74. "cell_type": "markdown",
  75. "metadata": {},
  76. "source": [
  77. "有很多种方法去初始化新的numpy数组, 例如从\n",
  78. "\n",
  79. "* Python列表或元组\n",
  80. "* 使用专门用来创建numpy arrays的函数,例如 `arange`, `linspace`等\n",
  81. "* 从文件中读取数据"
  82. ]
  83. },
  84. {
  85. "cell_type": "markdown",
  86. "metadata": {},
  87. "source": [
  88. "### 从列表中"
  89. ]
  90. },
  91. {
  92. "cell_type": "markdown",
  93. "metadata": {},
  94. "source": [
  95. "例如,为了从Python列表创建新的向量和矩阵我们可以用`numpy.array`函数。\n"
  96. ]
  97. },
  98. {
  99. "cell_type": "code",
  100. "execution_count": 3,
  101. "metadata": {},
  102. "outputs": [
  103. {
  104. "data": {
  105. "text/plain": [
  106. "array([1, 2, 3, 4])"
  107. ]
  108. },
  109. "execution_count": 3,
  110. "metadata": {},
  111. "output_type": "execute_result"
  112. }
  113. ],
  114. "source": [
  115. "import numpy as np\n",
  116. "\n",
  117. "# a vector: the argument to the array function is a Python list\n",
  118. "v = np.array([1,2,3,4])\n",
  119. "\n",
  120. "v"
  121. ]
  122. },
  123. {
  124. "cell_type": "code",
  125. "execution_count": 4,
  126. "metadata": {},
  127. "outputs": [
  128. {
  129. "name": "stdout",
  130. "output_type": "stream",
  131. "text": [
  132. "[[1 2]\n",
  133. " [3 4]\n",
  134. " [5 6]]\n",
  135. "(3, 2)\n"
  136. ]
  137. }
  138. ],
  139. "source": [
  140. "# 矩阵:数组函数的参数是一个嵌套的Python列表\n",
  141. "M = array([[1, 2], [3, 4], [5, 6]])\n",
  142. "\n",
  143. "print(M)\n",
  144. "print(M.shape)"
  145. ]
  146. },
  147. {
  148. "cell_type": "markdown",
  149. "metadata": {},
  150. "source": [
  151. "`v`和`M`两个都是属于`numpy`模块提供的`ndarray`类型。"
  152. ]
  153. },
  154. {
  155. "cell_type": "code",
  156. "execution_count": 5,
  157. "metadata": {},
  158. "outputs": [
  159. {
  160. "data": {
  161. "text/plain": [
  162. "(numpy.ndarray, numpy.ndarray)"
  163. ]
  164. },
  165. "execution_count": 5,
  166. "metadata": {},
  167. "output_type": "execute_result"
  168. }
  169. ],
  170. "source": [
  171. "type(v), type(M)"
  172. ]
  173. },
  174. {
  175. "cell_type": "markdown",
  176. "metadata": {},
  177. "source": [
  178. "`v`和`M`之间的区别仅在于他们的形状。我们可以用属性函数`ndarray.shape`得到数组形状的信息。"
  179. ]
  180. },
  181. {
  182. "cell_type": "code",
  183. "execution_count": 6,
  184. "metadata": {},
  185. "outputs": [
  186. {
  187. "data": {
  188. "text/plain": [
  189. "(4,)"
  190. ]
  191. },
  192. "execution_count": 6,
  193. "metadata": {},
  194. "output_type": "execute_result"
  195. }
  196. ],
  197. "source": [
  198. "v.shape"
  199. ]
  200. },
  201. {
  202. "cell_type": "code",
  203. "execution_count": 7,
  204. "metadata": {},
  205. "outputs": [
  206. {
  207. "data": {
  208. "text/plain": [
  209. "(3, 2)"
  210. ]
  211. },
  212. "execution_count": 7,
  213. "metadata": {},
  214. "output_type": "execute_result"
  215. }
  216. ],
  217. "source": [
  218. "M.shape"
  219. ]
  220. },
  221. {
  222. "cell_type": "markdown",
  223. "metadata": {},
  224. "source": [
  225. "通过属性函数`ndarray.size`我们可以得到数组中元素的个数"
  226. ]
  227. },
  228. {
  229. "cell_type": "code",
  230. "execution_count": 8,
  231. "metadata": {},
  232. "outputs": [
  233. {
  234. "data": {
  235. "text/plain": [
  236. "6"
  237. ]
  238. },
  239. "execution_count": 8,
  240. "metadata": {},
  241. "output_type": "execute_result"
  242. }
  243. ],
  244. "source": [
  245. "M.size"
  246. ]
  247. },
  248. {
  249. "cell_type": "markdown",
  250. "metadata": {},
  251. "source": [
  252. "同样,我们可以用函数`numpy.shape`和`numpy.size`"
  253. ]
  254. },
  255. {
  256. "cell_type": "code",
  257. "execution_count": 9,
  258. "metadata": {},
  259. "outputs": [
  260. {
  261. "data": {
  262. "text/plain": [
  263. "(3, 2)"
  264. ]
  265. },
  266. "execution_count": 9,
  267. "metadata": {},
  268. "output_type": "execute_result"
  269. }
  270. ],
  271. "source": [
  272. "np.shape(M)"
  273. ]
  274. },
  275. {
  276. "cell_type": "code",
  277. "execution_count": 10,
  278. "metadata": {},
  279. "outputs": [
  280. {
  281. "data": {
  282. "text/plain": [
  283. "6"
  284. ]
  285. },
  286. "execution_count": 10,
  287. "metadata": {},
  288. "output_type": "execute_result"
  289. }
  290. ],
  291. "source": [
  292. "np.size(M)"
  293. ]
  294. },
  295. {
  296. "cell_type": "markdown",
  297. "metadata": {},
  298. "source": [
  299. "到目前为止`numpy.ndarray`看起来非常像Python列表(或嵌套列表)。为什么不简单地使用Python列表来进行计算,而不是创建一个新的数组类型?\n",
  300. "\n",
  301. "下面有几个原因:\n",
  302. "\n",
  303. "* Python列表非常普遍。它们可以包含任何类型的对象。它们是动态类型的。它们不支持矩阵和点乘等数学函数。由于动态类型的关系,为Python列表实现这类函数的效率不是很高。\n",
  304. "* Numpy数组是**静态类型的**和**同构的**。元素的类型是在创建数组时确定的。\n",
  305. "* Numpy数组是内存高效的。\n",
  306. "* 由于是静态类型,数学函数的快速实现,比如“numpy”数组的乘法和加法可以用编译语言实现(使用C和Fortran).\n",
  307. "\n",
  308. "利用`ndarray`的属性函数`dtype`(数据类型),我们可以看出数组的数据是那种类型。\n"
  309. ]
  310. },
  311. {
  312. "cell_type": "code",
  313. "execution_count": 11,
  314. "metadata": {},
  315. "outputs": [
  316. {
  317. "data": {
  318. "text/plain": [
  319. "dtype('int64')"
  320. ]
  321. },
  322. "execution_count": 11,
  323. "metadata": {},
  324. "output_type": "execute_result"
  325. }
  326. ],
  327. "source": [
  328. "M.dtype"
  329. ]
  330. },
  331. {
  332. "cell_type": "markdown",
  333. "metadata": {},
  334. "source": [
  335. "如果我们试图给一个numpy数组中的元素赋一个错误类型的值,我们会得到一个错误:"
  336. ]
  337. },
  338. {
  339. "cell_type": "code",
  340. "execution_count": 12,
  341. "metadata": {},
  342. "outputs": [
  343. {
  344. "ename": "ValueError",
  345. "evalue": "invalid literal for int() with base 10: 'hello'",
  346. "output_type": "error",
  347. "traceback": [
  348. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  349. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  350. "\u001b[0;32m<ipython-input-12-e1f336250f69>\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[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
  351. "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'hello'"
  352. ]
  353. }
  354. ],
  355. "source": [
  356. "M[0,0] = \"hello\""
  357. ]
  358. },
  359. {
  360. "cell_type": "markdown",
  361. "metadata": {},
  362. "source": [
  363. "如果我们想的话,我们可以利用`dtype`关键字参数显式地定义我们创建的数组数据类型:"
  364. ]
  365. },
  366. {
  367. "cell_type": "code",
  368. "execution_count": 13,
  369. "metadata": {},
  370. "outputs": [
  371. {
  372. "data": {
  373. "text/plain": [
  374. "array([[1.+0.j, 2.+0.j],\n",
  375. " [3.+0.j, 4.+0.j]])"
  376. ]
  377. },
  378. "execution_count": 13,
  379. "metadata": {},
  380. "output_type": "execute_result"
  381. }
  382. ],
  383. "source": [
  384. "M = np.array([[1, 2], [3, 4]], dtype=complex)\n",
  385. "\n",
  386. "M"
  387. ]
  388. },
  389. {
  390. "cell_type": "markdown",
  391. "metadata": {},
  392. "source": [
  393. "常规可以伴随`dtype`使用的数据类型是:`int`, `float`, `complex`, `bool`, `object`等\n",
  394. "\n",
  395. "我们也可以显式地定义数据类型的大小,例如:`int64`, `int16`, `float128`, `complex128`。"
  396. ]
  397. },
  398. {
  399. "cell_type": "markdown",
  400. "metadata": {},
  401. "source": [
  402. "### 使用数组生成函数"
  403. ]
  404. },
  405. {
  406. "cell_type": "markdown",
  407. "metadata": {},
  408. "source": [
  409. "对于较大的数组,使用显式的Python列表人为地初始化数据是不切实际的。除此之外我们可以用`numpy`的很多函数得到不同类型的数组。有一些常用的分别是:"
  410. ]
  411. },
  412. {
  413. "cell_type": "markdown",
  414. "metadata": {},
  415. "source": [
  416. "#### arange"
  417. ]
  418. },
  419. {
  420. "cell_type": "code",
  421. "execution_count": 14,
  422. "metadata": {},
  423. "outputs": [
  424. {
  425. "name": "stdout",
  426. "output_type": "stream",
  427. "text": [
  428. "[0 1 2 3 4 5 6 7 8 9]\n",
  429. "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
  430. ]
  431. }
  432. ],
  433. "source": [
  434. "# 创建一个范围\n",
  435. "\n",
  436. "x = np.arange(0, 10, 1) # 参数:start, stop, step: \n",
  437. "y = range(0, 10, 1)\n",
  438. "print(x)\n",
  439. "print(list(y))"
  440. ]
  441. },
  442. {
  443. "cell_type": "code",
  444. "execution_count": 15,
  445. "metadata": {},
  446. "outputs": [
  447. {
  448. "data": {
  449. "text/plain": [
  450. "array([-1.00000000e+00, -9.00000000e-01, -8.00000000e-01, -7.00000000e-01,\n",
  451. " -6.00000000e-01, -5.00000000e-01, -4.00000000e-01, -3.00000000e-01,\n",
  452. " -2.00000000e-01, -1.00000000e-01, -2.22044605e-16, 1.00000000e-01,\n",
  453. " 2.00000000e-01, 3.00000000e-01, 4.00000000e-01, 5.00000000e-01,\n",
  454. " 6.00000000e-01, 7.00000000e-01, 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 = np.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 , 1.66666667,\n",
  484. " 2.08333333, 2.5 , 2.91666667, 3.33333333, 3.75 ,\n",
  485. " 4.16666667, 4.58333333, 5. , 5.41666667, 5.83333333,\n",
  486. " 6.25 , 6.66666667, 7.08333333, 7.5 , 7.91666667,\n",
  487. " 8.33333333, 8.75 , 9.16666667, 9.58333333, 10. ])"
  488. ]
  489. },
  490. "execution_count": 16,
  491. "metadata": {},
  492. "output_type": "execute_result"
  493. }
  494. ],
  495. "source": [
  496. "# 使用linspace两边的端点也被包含进去\n",
  497. "np.linspace(0, 10, 25)"
  498. ]
  499. },
  500. {
  501. "cell_type": "code",
  502. "execution_count": 17,
  503. "metadata": {},
  504. "outputs": [
  505. {
  506. "data": {
  507. "text/plain": [
  508. "array([1.00000000e+00, 3.03773178e+00, 9.22781435e+00, 2.80316249e+01,\n",
  509. " 8.51525577e+01, 2.58670631e+02, 7.85771994e+02, 2.38696456e+03,\n",
  510. " 7.25095809e+03, 2.20264658e+04])"
  511. ]
  512. },
  513. "execution_count": 17,
  514. "metadata": {},
  515. "output_type": "execute_result"
  516. }
  517. ],
  518. "source": [
  519. "np.logspace(0, 10, 10, base=e)"
  520. ]
  521. },
  522. {
  523. "cell_type": "markdown",
  524. "metadata": {},
  525. "source": [
  526. "#### mgrid"
  527. ]
  528. },
  529. {
  530. "cell_type": "code",
  531. "execution_count": 18,
  532. "metadata": {},
  533. "outputs": [],
  534. "source": [
  535. "x, y = np.mgrid[0:5, 0:5] # 和MATLAB中的meshgrid类似"
  536. ]
  537. },
  538. {
  539. "cell_type": "code",
  540. "execution_count": 19,
  541. "metadata": {},
  542. "outputs": [
  543. {
  544. "data": {
  545. "text/plain": [
  546. "array([[0, 0, 0, 0, 0],\n",
  547. " [1, 1, 1, 1, 1],\n",
  548. " [2, 2, 2, 2, 2],\n",
  549. " [3, 3, 3, 3, 3],\n",
  550. " [4, 4, 4, 4, 4]])"
  551. ]
  552. },
  553. "execution_count": 19,
  554. "metadata": {},
  555. "output_type": "execute_result"
  556. }
  557. ],
  558. "source": [
  559. "x"
  560. ]
  561. },
  562. {
  563. "cell_type": "code",
  564. "execution_count": 20,
  565. "metadata": {},
  566. "outputs": [
  567. {
  568. "data": {
  569. "text/plain": [
  570. "array([[0, 1, 2, 3, 4],\n",
  571. " [0, 1, 2, 3, 4],\n",
  572. " [0, 1, 2, 3, 4],\n",
  573. " [0, 1, 2, 3, 4],\n",
  574. " [0, 1, 2, 3, 4]])"
  575. ]
  576. },
  577. "execution_count": 20,
  578. "metadata": {},
  579. "output_type": "execute_result"
  580. }
  581. ],
  582. "source": [
  583. "y"
  584. ]
  585. },
  586. {
  587. "cell_type": "markdown",
  588. "metadata": {},
  589. "source": [
  590. "#### random data"
  591. ]
  592. },
  593. {
  594. "cell_type": "code",
  595. "execution_count": 21,
  596. "metadata": {},
  597. "outputs": [],
  598. "source": [
  599. "from numpy import random"
  600. ]
  601. },
  602. {
  603. "cell_type": "code",
  604. "execution_count": 22,
  605. "metadata": {},
  606. "outputs": [
  607. {
  608. "data": {
  609. "text/plain": [
  610. "array([[0.31850549, 0.64755869, 0.93737096, 0.06141188, 0.17055487],\n",
  611. " [0.95771684, 0.88466718, 0.81119863, 0.95268744, 0.73734857],\n",
  612. " [0.51036326, 0.8779331 , 0.41560197, 0.300393 , 0.42244209],\n",
  613. " [0.50866631, 0.84322931, 0.34459543, 0.47379641, 0.03312725],\n",
  614. " [0.96519922, 0.20557788, 0.38343937, 0.21493144, 0.27541461]])"
  615. ]
  616. },
  617. "execution_count": 22,
  618. "metadata": {},
  619. "output_type": "execute_result"
  620. }
  621. ],
  622. "source": [
  623. "# 均匀随机数在[0,1)区间\n",
  624. "random.rand(5,5)"
  625. ]
  626. },
  627. {
  628. "cell_type": "code",
  629. "execution_count": 23,
  630. "metadata": {},
  631. "outputs": [
  632. {
  633. "data": {
  634. "text/plain": [
  635. "array([[ 1.12204579, 2.90667688, -1.06379302, 1.52801804, 1.34553205],\n",
  636. " [ 2.22610261, -0.18597008, 1.12948162, -1.44339033, 0.14366645],\n",
  637. " [ 0.12767746, -0.04534549, 0.1536468 , 0.7333602 , 0.96510913],\n",
  638. " [ 0.30848743, -2.31710677, 0.37803085, -0.52433003, 1.39883453],\n",
  639. " [-0.52307504, 0.40612781, 0.48341866, -1.96277249, 1.1671546 ]])"
  640. ]
  641. },
  642. "execution_count": 23,
  643. "metadata": {},
  644. "output_type": "execute_result"
  645. }
  646. ],
  647. "source": [
  648. "# 标准正态分布随机数\n",
  649. "random.randn(5,5)"
  650. ]
  651. },
  652. {
  653. "cell_type": "markdown",
  654. "metadata": {},
  655. "source": [
  656. "#### diag"
  657. ]
  658. },
  659. {
  660. "cell_type": "code",
  661. "execution_count": 24,
  662. "metadata": {},
  663. "outputs": [
  664. {
  665. "data": {
  666. "text/plain": [
  667. "array([[1, 0, 0],\n",
  668. " [0, 2, 0],\n",
  669. " [0, 0, 3]])"
  670. ]
  671. },
  672. "execution_count": 24,
  673. "metadata": {},
  674. "output_type": "execute_result"
  675. }
  676. ],
  677. "source": [
  678. "# 一个对角矩阵\n",
  679. "np.diag([1,2,3])"
  680. ]
  681. },
  682. {
  683. "cell_type": "code",
  684. "execution_count": 25,
  685. "metadata": {},
  686. "outputs": [
  687. {
  688. "data": {
  689. "text/plain": [
  690. "array([[0, 1, 0, 0],\n",
  691. " [0, 0, 2, 0],\n",
  692. " [0, 0, 0, 3],\n",
  693. " [0, 0, 0, 0]])"
  694. ]
  695. },
  696. "execution_count": 25,
  697. "metadata": {},
  698. "output_type": "execute_result"
  699. }
  700. ],
  701. "source": [
  702. "# 从主对角线偏移的对角线\n",
  703. "diag([1,2,3], k=1) "
  704. ]
  705. },
  706. {
  707. "cell_type": "markdown",
  708. "metadata": {},
  709. "source": [
  710. "#### zeros and ones"
  711. ]
  712. },
  713. {
  714. "cell_type": "code",
  715. "execution_count": 26,
  716. "metadata": {},
  717. "outputs": [
  718. {
  719. "data": {
  720. "text/plain": [
  721. "array([[0., 0., 0.],\n",
  722. " [0., 0., 0.],\n",
  723. " [0., 0., 0.]])"
  724. ]
  725. },
  726. "execution_count": 26,
  727. "metadata": {},
  728. "output_type": "execute_result"
  729. }
  730. ],
  731. "source": [
  732. "np.zeros((3,3))"
  733. ]
  734. },
  735. {
  736. "cell_type": "code",
  737. "execution_count": 27,
  738. "metadata": {},
  739. "outputs": [
  740. {
  741. "data": {
  742. "text/plain": [
  743. "array([[1., 1., 1.],\n",
  744. " [1., 1., 1.],\n",
  745. " [1., 1., 1.]])"
  746. ]
  747. },
  748. "execution_count": 27,
  749. "metadata": {},
  750. "output_type": "execute_result"
  751. }
  752. ],
  753. "source": [
  754. "np.ones((3,3))"
  755. ]
  756. },
  757. {
  758. "cell_type": "markdown",
  759. "metadata": {},
  760. "source": [
  761. "## 文件 I/O"
  762. ]
  763. },
  764. {
  765. "cell_type": "markdown",
  766. "metadata": {},
  767. "source": [
  768. "### 逗号分隔值 (CSV)"
  769. ]
  770. },
  771. {
  772. "cell_type": "markdown",
  773. "metadata": {},
  774. "source": [
  775. "对于数据文件来说一种非常常见的文件格式是逗号分割值(CSV),或者有关的格式例如TSV(制表符分隔的值)。为了从这些文件中读取数据到Numpy数组中,我们可以用`numpy.genfromtxt`函数。例如:"
  776. ]
  777. },
  778. {
  779. "cell_type": "code",
  780. "execution_count": 28,
  781. "metadata": {},
  782. "outputs": [
  783. {
  784. "name": "stdout",
  785. "output_type": "stream",
  786. "text": [
  787. "1800 1 1 -6.1 -6.1 -6.1 1\r\n",
  788. "1800 1 2 -15.4 -15.4 -15.4 1\r\n",
  789. "1800 1 3 -15.0 -15.0 -15.0 1\r\n",
  790. "1800 1 4 -19.3 -19.3 -19.3 1\r\n",
  791. "1800 1 5 -16.8 -16.8 -16.8 1\r\n",
  792. "1800 1 6 -11.4 -11.4 -11.4 1\r\n",
  793. "1800 1 7 -7.6 -7.6 -7.6 1\r\n",
  794. "1800 1 8 -7.1 -7.1 -7.1 1\r\n",
  795. "1800 1 9 -10.1 -10.1 -10.1 1\r\n",
  796. "1800 1 10 -9.5 -9.5 -9.5 1\r\n"
  797. ]
  798. }
  799. ],
  800. "source": [
  801. "!head stockholm_td_adj.dat"
  802. ]
  803. },
  804. {
  805. "cell_type": "code",
  806. "execution_count": 29,
  807. "metadata": {},
  808. "outputs": [],
  809. "source": [
  810. "import numpy as np\n",
  811. "data = np.genfromtxt('stockholm_td_adj.dat')"
  812. ]
  813. },
  814. {
  815. "cell_type": "code",
  816. "execution_count": 30,
  817. "metadata": {},
  818. "outputs": [
  819. {
  820. "data": {
  821. "text/plain": [
  822. "(77431, 7)"
  823. ]
  824. },
  825. "execution_count": 30,
  826. "metadata": {},
  827. "output_type": "execute_result"
  828. }
  829. ],
  830. "source": [
  831. "data.shape"
  832. ]
  833. },
  834. {
  835. "cell_type": "code",
  836. "execution_count": 31,
  837. "metadata": {},
  838. "outputs": [
  839. {
  840. "data": {
  841. "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0UAAAEWCAYAAACpAjzFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOydd7hcVdX/vzsFAoFAgNBLqNJBKRZsIKDYK6/4vooV66v+1FcjIqCigCBFBCnSe4dAEhLSAwnppPfee7m5uX32749p6+yZvWbNmT3t3vV5njyZO3PKPufss/de3VhroSiKoiiKoiiK0lXpVu0GKIqiKIqiKIqiVBMVihRFURRFURRF6dKoUKQoiqIoiqIoSpdGhSJFURRFURRFUbo0KhQpiqIoiqIoitKlUaFIURRFURRFUZQujQpFiqIoSqfGGDPEGHNltdvBYYxZboy5uNjfBMe1xpgTSmudoihK50eFIkVRlBqmlAVxNTHGXG+MeaLa7QAAa+1l1tpH4+xrjPmwMWa8MWaHMWarMeZtY8x5qd++bYx5K2xrFUVRlGrQo9oNUBRFURQXY0wPa217ldvQB8DrAH4M4DkAewD4CICWarZLURRFCY9aihRFUWoUY8zjAI4G8JoxZpcx5rep7z+Qsl5sN8bMMMZ8nOwz2hhzQ+r3XcaY14wxBxpjnjTG7DTGTDbG9CfbW2PMz40xS40xm40xtxhjupHfv2uMmWeM2WaMGWqMOYb8dqcxZlXquFONMR9Jff8pAFcD+K9UG2akvo9Yvag1yRjTP9WW7xljVgIYyZ3fJLndGLMxdf5ZxpjTPfdxtDHm+6nP3zbGvGWMuTV1zGXGmMs8j+AkALDWPm2t7bDWNllrh1lrZxpjTgFwL4APpq5xe+r4+xljHjPGbDLGrDDGXOPczx+krqfBGDPXGPO+PO09JdWuK8jXZxtjZqYsVs8aY3o5x1ycsmQNNMYc7rkPjxhj7km5E+5KWb0ONcbckboX840x7/XcC0VRlE6NCkWKoig1irX2mwBWAvictXYfa+3fjTFHABgE4AYABwD4DYAXjTH9yK5fB/BNAEcAOB7ABAAPp7afB+A651RfAnAugPcB+AKA7wKAMeYLSAo3XwbQD8A4AE+T/SYDODt13KcAPG+M6WWtfQPA3wA8m2r3WUVc9scAnALgkwXOfymAjyIpuOwH4HIAW4TneD+ABQAOAvB3AA8aY0ye7RYC6DDGPGqMucwY0zf9g7V2HoAfAZiQusb9Uz/dlWrPcalr+RaA7wCAMeZrAK5PfdcHwOfdNqeEpKEA/tdaS+/15QA+BeBYAGcC+HZq+4sA3Jj6/TAAKwA8w1z75QCuSV17C5J9Y1rq7xcA3MbsqyiK0mlRoUhRFKW++B8Ag621g621CWvtmwCmAPg02eZha+0Sa+0OAEMALLHWDk+5oz0PwLUG3Gyt3WqtXQngDgBpC8WPANxorZ2X2vdvSFosjgEAa+0T1tot1tp2a+0/AOwJ4D0lXt/11tpGa21TgfO3AdgXwMkATGqbdcJzrLDWPmCt7QDwKJLCxCHuRtbanQA+DMACeADAppQlJmdbADDGdEdSIP29tbbBWrscwD+QFFAB4PsA/m6tnWyTLLbWriCH+AiAgQC+Za193Tn8P621a621WwG8hqQwCgD/DeAha+00a20LgN8jab3q77n2l621U621zQBeBtBsrX0sdS+eRW7fUBRF6RKoUKQoilJfHAPgaynXue0pt60PI7mwT7OBfG7K8/c+zjFXkc8rAKTdr44BcCc5z1YABkkLFIwxv0m5gu1I/b4fkhaHUqBt8Z7fWjsSwL8A3A1gozHmfpOMAZKwPv3BWrs79dG9J+nf51lrv22tPRLA6Ujemzs8xz0IQE8k72GaFUjdLwBHAVjCtOtHAMZba0dzbQawm7T3cHo+a+0uJK1PRyA/xfYNRVGULoEKRYqiKLWNdf5eBeBxa+3+5F9va+1NJZzjKPL5aABrybl+6JxrL2vt+FT80G+RdMfqm3If24Gk0JKv3QDQCGBv8vehebah+3nPDwDW2n9aa88BcCqSbnT/V9RVF4m1dj6AR5AUjty2AsBmJC1Yx5DvjgawJvV5FZLujD5+BOBoY8ztRTRrLT2fMaY3gAPJORVFURQBKhQpiqLUNhuQjE9J8wSAzxljPmmM6W6M6WWM+bgx5sgSzvF/xpi+xpijAPwCSTcqIJlI4PfGmNOATBKBr6V+2xdAO4BNAHoYY65FMk6Gtrs/TTIA4F0AXzfG9DTGnAvgqwXa5T2/MeY8Y8z7jTE9kRS2mgEkYl29B2PMycaYX6fvber+XAHgndQmGwAcaYzZAwBSLmjPAfirMWbflJvfr5B8ZgDwHwC/Mcack0oUcYIhiSsANCAZN/RRY4xUyH0awHeMMWcbY/ZE0sVwYsp1T1EURRGiQpGiKEptcyOAa1IuZL+x1q5CMhnC1UgKJKuQtJCUMp6/CmAqkkLLIAAPAoC19mUANwN4xhizE8BsAOlMbUMBvIFkMoIVSAol1PXt+dT/W4wx01Kf/4ikpWQbgD8hmZzBS4Hz90Eyzmdb6vxbANxS5HUXogHJpAwTjTGNSApDswH8OvX7SABzAKw3xmxOffe/SAppSwG8heQ1PpS6nucB/DX1XQOAV5BMUpHBWrsdwCUALjPG/KVQA621w5G8ry8CWIfk/f16vMtVFEXpuhhr83k4KIqiKF0BY4wFcKK1dnG126IoiqIo1UItRYqiKIqiKIqidGlUKFIURVEURVEUpUtTNaEoFRw8ySSrsc8xxvwp9f2xxpiJqercz6YDWBVFUZTwWGuNus4piqIoXZ1qWopaAFyUqnR+NoBPGWM+gGRQ7e3W2hOQDKD9XhXbqCiKoiiKoihKJ6dHtU5skxkedqX+7Jn6ZwFcBOAbqe8fBXA9gH9zxzrooINs//79y9JORVEURVEURVHqn6lTp2621vbL91vVhCIAMMZ0RzIN7AlIViVfAmC7tbY9tclqeKpyG2OuAnAVABx99NGYMmVK+RusKIqiKIqiKEpdYoxZ4futqokWrLUd1tqzARwJ4HwAJxex7/3W2nOttef265dX4FMURVEURVEURSlITWSfSxWrGwXggwD2N8akLVhHAlhTtYYpiqIoiqIoitLpqWb2uX7GmP1Tn/dCsoL3PCSFo6+mNrsSyUrriqIoiqIoiqIoZaGaMUWHAXg0FVfUDcBz1trXjTFzATxjjLkBwHQAD1axjYqiKIqiKIqidHKqmX1uJoD35vl+KZLxRYqiKIqiKIqiKGWnJmKKFEVRFEVRFEVRqoUKRYqiKIqiKIqidGlUKFIURVEURVEqyrSV2zB37c5qN0NRMlS1eKuiKIqiKIrS9fjyPeMBAMtv+kyVW6IoSdRSpCiKoiiKoihKl0aFIkVRFEVRFKXT0tDcVu0mKHWACkVdhG2NrZi0bGu1m6EoiqIoilIxJizZgjOuH4YxCzdVuylKjaNCURfhG/+ZiMvvm1DtZiiKoihKxWlq7cCSTbuq3QylCkxdkVQIT1q2pcotyTJ7zQ70HzAIU5arsrqWUKGoizBvXTLDi7W2yi1Rapmtja1IJLSPKIpSHLtb27G7tb3azfDys6em4RP/GIPW9kTOb4NmrlOBSako4xZtBgC8OW9DlVuiUFQo6mKMnL+x2k2oG6y1GDRzHTq6iJCweVcL3veXN3Hbmwur3RRFUeqMU68dilOvHVrtZnh5a3FyEZrIoxj8aUpgUjontagLbm7rqHYTysJtby7E3aMWV7sZsVGhqIvR3JarJVPyM3DGWvz0qWn4z7il1W6Kl/4DBuFXz70b5Fibd7UAAIbNXR/keOXmkbeXof+AQdi+u7XaTVHKxH1jlqh7iZLD4o27sGN3cYHztbIuXrC+Abtaatei1pkxMNVuQoY7RywCALy7cnuVWxKWf45YhFuGLqh2M2KjQlEXw5Zpahg+d0OnW7xsakgKCRt2tlS5JTwvTVsT5Di1NGFIeHrSKgDA+p3NVW6JUi5uHDIfX71XYyGVKBffNgafuWtcwe1efXcN5q+vreKgn7xjLL778ORqN6PTs313K+4bs6TmQwZqSUC+d8wSnHbtG9VuRlVRoagOefCtZfh/z4axDrhYa/Hi1NVo6yjOovT9x6ZUbPFSbNuUzk2Nz3mKEsFai3Ydw0pm9bamgtv84pl38ak7CgtPlSK9QJ/UyRSItcjvX5qFG4fMx8QyZN211uKV6WuCuMCZGtJF3jRkPhpbO6dbnxQViuqQv7w+Fy9PD2MdcBk4Yy1+/fwM3Dt6SVmOXyqzVu/AiX8YglEaG1U2QgoZCzc0ZCxuiqIAV788Cyf8YUiw41lrMX7J5prXiCtdk+cmr8IrZVqvcDQ0Jy0wVIkaylNm3KLN+OWz7+LmN+aXfKy129XToZZQoagCXHLbGFz12JSC2+1oasOWXdVdQG5rTMZnbK5yO3xMTmnYtN5AfFZt3Y0HxlYmTurS28fiI38fWdZz5NO0rd3elNHird3ehHvrwI1CqW82NjTjN8/PKNjP0m6foRgyez2+8cBEPPHOCna7RMLijuELu24MnvD139XSjtuGLSiLNa8rDkG/fXEmflkmz5ZiCeUivqMpGc+2MYBr/dbG+O9j/wGD0H/AIDQVYd1pbutA/wGDCo4Xre0J/GPYgqKO3RlQoagCLNq4C8PmFk67eO4Nb+KcG4YDSC5c3xTsUyyVGJQTCVu21Kzp5udbCD83ZRU+/6+3ynLezsQ3H5yIvw6eV5QAvmN3G16evjrW+aqR3ONDN43Ej5+YCgC46vEpuGnIfKzYsrvi7VC6Duf/dQRemLoaD7+9vKLnXb0t2a8L9e9RCzbijuGLcN3AOZVoVs1SyF3p1qEL8M+Ri/HKu2sr0yCl7khnMKwV17dilNjbUwlK7hq5iN3uqYkrcNfIxbhndP1mkouDCkU1RFtHVmL59D/H4QcC61KxVEJRdeOQeTj12qFF+dtOWb4Vv3thZkEta/r3fJv99oWZmLl6R1Ft7Yqk3QrcW5ge4PM9gZ8/Mx3/79kZBWt5JBIWv35uBt5dVf2MOqMWJK2J6ett1TiOinLjkHkYXgbFTqVpbuvAjx6fihVbGkXbL9ss267SpOvz1HIq4EUbGrCyzMqLQorBxlTge0eiDJai4EdUJKTv+7ZAVtJ0H+rerUakojxc88osTFiSLFabSFiMWrAx7/rq9Zlrccfw3DIcLXUwXpQDFYpqlPRCrhBD56xH/wGDsG5H4aDTSvHAuGUAspOLhMvvm4Bnp6wqWBMo7Tb3yPjl7HbWWixY3yA+f1fCd4e54T3dvwoludjS2IoXp63G9x6pnexKaQ36zUNK9/9W5Nw3Zim+XwbFTqUZOX8j3pizHv/3wkzR9rWiPQaA9Tua8Y9hC2BtNpoi7UK0cWdzSa47UpZvbkT/AYMwVuDyfMntY/HRW0aVvU0c6SnIlOFBxnXhHb94M16cGs9SH5L+Awbhz6/NrXYzYvPkxJVBjpOxFAU5WpKtja3YGDCT6hPvrMQVD7wDAHhswnJ85+HJeG3muozSJp1V92dPTccdw3OtRrU0jlUSFYrqnGcnJ/3T56yRpR2tZD8vpuZp1i2Ob6HUh/fJiSvxyTvG4u1UwT4li40xoKefZTdjYK1F/wGDcN5fh+ceG2m3gsr1NOk6Y8XW4jTQ594wHA++tSxGi5Rq0tzWEdR995nUGDtJmMWqWmuJfK/c/z49DXeNXIzZa3Zm3pP0duf/bQTe95c3Cx739ZlrI9abbUUKUulMa6+m3NEaW9rR0l672uf0GNathlaF3/jPRPz6+RnVbgYA4KG3yzMmjlu0CbPqxNPDkvkwFO/7y5s4/28j8v720rTVJaWWX5XK1LhhRzMmLtsi2mfQzHUAoh5MaSYv34r3XDOk6LGgHlChqM6xRfq2hjLfW2vxxuz1bDBqMVqxzIRdaDvhFcxZmxxAlgtdXroiPsEl33NLf9fNZAfJfFnl0h4ntZioo0cRrg5rtjdh864W/OX12tGKtnUk8Mbs9RVJGLFhZ3PF6o6t3rY7qLvlJbePwanXDg12vPcfewAA4MSD9wl2zJBw3aGJuL5kFRbFHf9nT03HZXeOBZAUDN/7lzfxxuwiCjxnFpDJ/0+7biguu7PyabKlc8ea1AJyZ1NxxWFlbSiNciQYautI4MqHJmFGgXew3Gnkv/ngJHyuTmKCE9IFS0xWbtmN/7pvAhqa22Ctxa+em1FSavmRqWy9xsiV1TNSAmo+l8N7Ri1GS3sC01dti92mWkWFojqHSzxQTt6cuwE/emIq7h7lT91djKUoTaHriHPMzsSkZVvxcImauu2eyZ6791KXkqYq+B9L+37P7vLhbo2gBkqluWvEIvzoiakYtaD86egvvX1s0XXHmts6cO2rs7GzubjF5IdvHoUv3v12zvfSGB4AOOmaIbji/qSryKqt2WfX1pHAK9PXFOXK63Jg7z0AAO89en/R9pW0khYiraQwhiqeim9funZJeuE8uYDAPCzl1r18c2NmAfnmvGx82dJNtausSte1eW1m+EQLpeozpq0Ivwidt24nxizchN8WcA/NZzHIR0t7B77xwDtYuz3cGLp2e1PRrmXlKlSfPHaSclkTbx++EBOXbcWwORvwRACXPxrnWGysHBcjaW38cb9WUaGozuEmul0t7WWrlrx5V1J7wMUyJQJptNdub8JTqYFBcsxCmvSVW3aj/4BBmL1GZqovNO49PWklTvrDkILxUC4bYvgPX37fBPypRJ/uQkqufFeRHhhfnsbXm4j7zD/xj9G4cci8ovYpdtLr2b12FqtxWJ1aZGzZVZzLwkf/Pgq3DVtQ1D47YmjJn560Eo9NWIG7RvBZjaQ0tsgF7Nb2BCYszXULuWnIfPzy2XfxsVtGB2lTvUHHpBAKtASxGAPA4xOW512sDpyRFChmrtmROW8661W1kQ5RteQ+l6YcTfrjK7MBAOtTz7G5rQM7SnhWL01bg/FLtuBDN4UrxfChm0Z6XcskhDauW+c9WLihIdPnb35jPvoPGFSSKyB9zHOE6xQJTa0dRVsb08mrNu5sJp5J2RY+OTE57v9rZDRLXbHroVpBhaIapCi3s/SHPIPl6dcNxenXhXMjyQc3SC/YUHyig3xa1v95cCKufnkWduxuE2kYk7fPfw9HzE9qLJ+fIqsXUuhxXD9wDlo7EpnsThJemrYa7//bCEz1aP4SCVt2NyljkgNdNgC68Iw7euFGVhiJ2+Ylmxpx35h4tZPSCoFEgUG4mDG6BtdDrIZ/U0MLRnssSCu37sY/UxOWtbbgfYpLehKspSR/abc8nztnOe5FtfpOvrFza8r1JWkpKj3ej8YWrtyyG398dQ5+mEp9n68t1lpWUWKtZRdPxT6fjoTF5fdNyJvUodihqXsp98kzfpdqvQhVZ4eSdpNqSGn6P33nOJz152EAkvPUjx7Pfb5AsrTD0Dm5bpShlKE+pHPj5obyxbvQ9wBIWtZ//vR0AMC/U4Xvn5qUrANU6lyejmnkcLuq73y3D18Ya3xevHEXzv/biLwxtmnLk/uuFkrKVKuoUFQm5q3bWVDbaq3F9x+dnJMM4NUY9RGkQ2Whl3PtjqS2qD3AYqGQVUFKWjMuHWxDDcppd4FCgaXps/3h5Vk5v+3Y3ZY3QDLtfuLLkHfc1YMLBtaGEJq+ePfb+NZDk8TbL9+8m11cFJMSfdKyrUEWpRYWI+ZtwHFXD8a8df5g1GLiVmpFJlq7vSknRXG+O/a1e8fj2w8Xzvh35cOTcdzVgwO1Ljyrt+3GF+5+G7ta2svq/gIAb8xej+OuHoxFBZQ3bta2Wat3sO545Vi4xqXv3j0BAD26dRPHbXJknonJprjPN8+lNejW8sLIo+OX4/irB+etmTZl+VYcd/VgcYILIBn/MGnZ1rzFQtNzmjQJRynC7XFXD8bXinQ/lVBOgTv9mJYSd6lfPTcDb6QEHzeGdNyizfhhHoGp3BaC464ejN88XzgTZBylrJSEQMGQ7vfHXT0Y175a2dpgvncuYeOtG1ZuTfYJLnFVvlsxfeW2or0Uqo0KRWXisjvH4b/u4wfFrY2tGD5vI/77PxNzvpfQ3pEIbk24f2xSWz+xwES0bDNfrwbwx66kmbBkS1EFaqUTQnJMjm787qrtGfP2bmGF5iZn8jz5j0Pwj3wveOoRvDQ9Vwg868/Dig6QTGdmeqmAUBni0aeF4OiBk/9d9+psfMBxWdjV0s6e91fPyTIkjZq/EZffNwEPF0itLmXYnGQ/Kld9pCvufwfffHBiwe2GzVmfqQ0hpaW9A7e/uTBvPYgP3TQSH71lFGav2cH2/+XC2i6StMjF8J9xS9F/wCB2HCpGY/jhm0dhxqrteChQ1j/u3Gkt96wC7ik0a1tjSzs+96+38LOnpnm3z/ecFm1owDOTorEBxSYj+fbDk/C1e8cXtU8+SllY06xbXBbL9HcWvJb8xdQYtyZP/Ek6pm3wrHVsm6av3JYZ29PWem4OfeIdWYxGqTVopqS8AJpaO7CxITnOljpml1PcLtS2PwuTzlSirs2L07LpyVdv2102QYy+c40t7Zl3Nn06PtFU9vPj76woS/tqAV+/MQb40j3jM14K9YIKRWVkfh4rwOKNu/DBG0dgU0ML7izR934lSTFsjMG2xlZccNNIzF0bP3Ujx5y1OzB1RVJYStci4ihkBbjigXdEBWqLFfyS2szoPl+8++2MefuWoTLNhfsyN7clcFeeF1yi0fZNFPn2feTt5aL2lYp7W9OLpbSm8NEJKzJ+5pH9Amjw0/ExSzbtYtN6JhIWz05eyS5uQ2nmrbXe5zRh6RaMW5RfS9bc1pHpo1c9PjVTG0LKo+OX484Ri9j034PowrCGXLVvGJSMA+Ne0VB6m+T4U1ygOWe5TAuvLUW4vaYX3enCwFIuuX0sBrwUtST/5vkZaO9I4JO3j8XIlEvvvWOW4Mcpd7RZq3fgwzePzFhiRi/YhMnLc69fenu593bLrpZMCt7IPs7Dc2MpgPza8sGzkgJnIpGtE5aP9HG4qWLJpl1o60jg2ckr884pX7pnfGZsT2vwD9+vl/d47n3wzS9uTFFzWwcuvHU0xi8prszD1++fgPP/Gj8ephSa2zqCWOPXbG8Sz8O+8biYRAkrtjSKYl/Wbm/Ch28ehVvLZI2g79xld47DuTcky1CkLcXP10DtqHxwT6oUTxpuT85qVk/xRSoUVZgH31qGdTuaMWzuejQJLRY+1u9oJpo7YOyiTVizvQn/HhPNCFco1WY+duUpHvuZf76Fr/zbtX75X4TQvsX5BttpK7fluG9ITxsqSxTNytORsPjN8zOw0DHdL97oWtb8525uK7xIW7O9qeS1cdz94z7WV99dg/vHJvtmRpNsgbcYk/yL01bjdy/Own1j/FkOS2HDzuaMy93doxbj5D++ge0Fqp43trTjp09Ow6aGFuzY3YaT//gGrhsYdY9o60hg0Mx1Gf9yjvTz5jSsBrXj0kdJv0LFTsIzVm0vusZFcvwpzVKyZNMurEopk9ICP5ddyUWSXVEaW9jY0o6tja1YsKEBv3sxKTDdNGQ+hqTSXd8xfCFWb2vC5CLcx4CkBSqdRIbees597gePTcFPn5qW0YRPXbE1r1U4Uq8s9V3u2JZ1rUtYm1exkiYdz/LWIv8C2BiD+8cuxe9enIUXmEWo1CLpXpNvPOvmWIqWbmrEss2NRRcvnUEE81KnRLdNHM1tHTj5j2/g5qHJotWLNjTktchJuKBA0oQdTW2YtjIpPPim1a3OuLqKqRv3sVtG40qBW3fapa8S9QipEvrmNwoXAqdxfIUIbV3jzhunD/oEXXosV+il+zwnjN+uBVQoqiLcZOHy1MSVmLk6KtxYZBccVBB3NUPUpSgtsZ97w3D89Em/C0gxbfMRRzuQr6if7yhtHQl8+Z7x+N4j0VgKa7OxOu+uLI87lY8lm3bhhamr2XsLkMVknouTyGqt7bzr5PcfnVxwIotL3Hn9F8+8i78NTk4m2Wu0bIrptMC7tTHXFTPvvSuyTRfcNDJTM+XllPvj5l0t7DM47bqhGDRrHe4YvhCbdiXfk8cmRN0jZqzajp8+NU00eaYnxHyLy3yEirXpSFjxOX1khVu+TdZa3D1qcWYh9IW738bXCrgXl4NP/GMMPvL3UZHv8j3qN+duwIhUCmla3+e1GdF4z6/fPwGX3j4m8p3UVcbAlMXod9md4/DZu3LrvXAFJ1enUtC3d1jsaGrDV/49AT95clpO+9JCoYFscZVrs8/PeMbltJvJuhpyaX9vFXoApNuzfHNjchxlzgsks5XmW7Q+PWkl+g8YxMaXFZsKnsa3LdvcWFKwevrcz6UC9S+5fWxJcwJnUf3Ow5Pw5XvGFzXntwYIxG90XNzHLNyU425prXzMtNZi8cbCsUiivm+BBuHzd2O43esqxPbdbUgEGM8LMTqPhTzd8leYWPh8MYO1StWEImPMUcaYUcaYucaYOcaYX6S+P8AY86YxZlHq/77VamN5KH4afH3mWlz98ix8/l/RWh7WZieTXz/3LpZvTi44BuUMCrnn3LyrJbPdv0cvwVdL1MDmI45QxNZKcOby9PHdmICEtZiWEoaGMEUGuXTipVLo2rM+9/EwADqYkXn4vI0FtYJuv5AKFCEsgFSLJElNzgkpxkQnvWLcLelklP60S5gK2iKMa9g9KWsS11eB3Hvwxuz1WF6ElcPl2ldn4+LbxrCJBgrFaKUX2IUsRXPW7sQtQxdEBBJuAi8UoA8kF8hBYipNUsHy6PjlaO9IoK0jgR88NgXfe3RKpi3pDd2zvbN0KxZuKO9CpBCuBYgGxNN3lSs4md7KGKAlJQDMXbsz5/6mLZ/SRDw7m9pE4wonFFkL7E69k9zCfGkR78LWxlZ8/NbR+N2LM719qLsxaOtI4KO3jMLPn56es7BO34v0/X5+yqoc66cbN8Ytzt+cuwGX3D4Wr767BhsbmnHhraPxp9cKB+j7BMW0J0Sh2F6pwwRn0U/Pwe2JhDiVeameMgDwjQeicZ5XPjQJP8mjkFzEvKN/em0OfvJk0mX1wbeW4eLbxgaLTT3z+mGi7dw5degceZWaZ50AACAASURBVKw1kBzL7x61GBffNoZNNgTEXHM4j5QqCSpQS7yiVNNS1A7g19baUwF8AMBPjTGnAhgAYIS19kQAI1J/d0qkg8fVL+VmNQOi7gKbd7VmgjldVm6NLo5dTcjNb8zPBIWGJM7iOW/chucw2ZoZJu/3hdqwLU8thnnrduZdaBaTbhvIP0EPnbM+UxMiH2MWbkJTa4dYOHlsfFQj/fDby0TuWmlCuc+Nmr8RA14snA0ouz8VYPiYoEoOuOl079e+6n9GLpLmhRC+6XnS9+RHT0zFRf8YHfuYT6Zqf83zZEAEkoIXR/rVo++ZO6wlLDB8XnGT/OPvLGd/39TQgjOvH4a7R5UexGtg8Mjby3HdwDl4/J0V3no6oTN/NbS0h3WJzHOwJak+3dLekZNFr+DhjL9/Jy1AhXv/DYPmleymbAHsvWd3AECvnt29bldizzJrcW/KHffl6WsiV0GVWcaYjDA2jCQEyqQbT+3ZnrBYumkX/u+FmQVjZLnxLO1yPX99A3amBBk3aYt7K0ct2Igzrx+WN84pnfU0xwUyRMZP56DpOTiRkD8H18W8FLhTJqxFu1Ow9K1Fm/Gr55IZCh9+e3kmBi7thse59pUDX7+QKpZbOxKYmnJfXL+jmX0zYymSnF3SSoxOJg8BqKJQZK1dZ62dlvrcAGAegCMAfAHAo6nNHgXwxeq0sLxY659kpXOIW/Hd10FXb8u+4NbKYlaKwfeSTRO6rsUNwkvv5w7CdPzjhKJ8rg2X3TkOH791dM73EjcogJ/0fvj41FzXmtQOv39pFq58aBJ++ex00fM3Jjdj059em5vTTmn62aJwrvE7j0zOW0vBl2584Iy1EfdB0fUiqXXtP2AQG1cgof+AQeg/YJD392KKo0rml3tGlR4PlYwpyr1R+V4day3+/sb8yHvPEWaRlP8zkHwH7xheXFKZzQWeQdq6OGgWL7RJaG7ryLhpNjT7U4FLrFfFQDW6brpjIOyCY3drR+aAhd63rPDkHz+7Gfm9KNWa19zWkUlLb631ul11MwY3Dkm75xpH+RK1CNPipLR5D5PyC90MMGl5bjxX2rK6KqVsvPy+CRn3Q065mE8I6D9gEG4cnK9otd8C29zWkTlWOl15voyXvjiVOIWZC5G24E1ctgXdu+dfVrrjl9TC6qu/Fj0436ndLvg/D07Mm901nUAlTlmUnHMW8Qb73pGePeQKBelrtkRQ6zEEUe+NipwyCDURU2SM6Q/gvQAmAjjEWpv2/1oP4BDPPlcZY6YYY6Zs2hQ2zWw5mbg0OYg9IkxFvKmhxatpc9cyvsUNtaSE1nYaUzh1dL4Jn0ItXtZatHck0H/AIHw6FeuR9st1A/ncAmrZ74mliJH/inlRC5mki8V9Dk+n0vUOnbNBpFk1MGwsThrOzSU3+5ysc0gHe1+Wpk0NLZGUvZzFlD7LtAXv6Um5KXWtdMEXeHSWWEN7phYJm3e1iASQN2avz6lttWpbVgAudIQFGxpwz+gl+PETfFxb9niF29Tc1pEp7vi/T0/PFHRMJxmhrjANzfESnxRDyMKAdCzO132oa1kxfPPBiUVZUF3W5UuXXwCfS9J+e/XMxkbl+Z161mVrsDBJCIwRP9dS3W0XbmjAiPnJsY5zCe5mTCSDHnXPdFN00xo2tP+vJu+ZOy6lL6M9YSPJWLY2tuKA3nsAAPofuLe3fcnaW7ncNza3aLXJDpA5DHhxJi69fSwWb9yFtpQwki8rqpSQS4Khc9aLjzfBMz+4wuNrM/iU7EDhayi2BxZr2c57ziJO6psWpFZdmvikHBl5OHdC0fyRJ1a8Vqm6UGSM2QfAiwB+aa2NrARscgWT945ba++31p5rrT23X79+FWipHG4BnXarkgbETcmjqUrjTjY+Fy86thc7P63Z3lSweN5CJjBx4tItOO+vw/MWNvWxO+3T7txH17UuvcB1gxnpfeHiborB9Xm/d8wS3DgkV8MnXTgZRhMowcJ6U91STSCbKpmcfUQRk4DUsEDPnXDcUuh94u5ZOm39RiJYp597vmbcOyZ3geFrE8fOPNkXXbY1tuKBcfz5gGRM4MadzTj3huF5/d1dfvTE1JzaVlsbWyLWNY60IqBQ/Z1iuPDW0Tgj5R//2oy1mYKOaVYQdxM3TW1oQRQA/uu+4tKeF4Kb2NPJWriaJPkYt2hzwWr03J1JzyMFi4CTo6zZnn9MoBbq3XktCEQqStHclvD2tYEz1orj+Hw/uS5Ko+bnV/K0k+yeBn5hzB1HvK5/NrrIi4xT5I9u3fzX5ctCuPcePTxnjdZ24uCmEAOTCWj//qOTWaXXoJmlW1F9bPQoOts7Sk8D8+q7USWrzx2vUJbQNKFHn3Kkly51jDTkGNIkKMWwllFGSEIL7g7gLVEpqioUGWN6IikQPWmtfSn19QZjzGGp3w8DILCd1hZLNskEHmlMkQ9px6fn4awL+WKSPvb3Ubi8hCxRaUEmHb+QD7EbhvO3b2yighA3gJUybtw0ZD7uy7MAl16LdIHrYyBj3t/lCIkrt+xG/wGD8NqMtZlUvS7vrtoeGZjXM1pq6QBuPZ8NgBtez9a34d6CdKHdOWuzxUvds9P9l21uLCAIFsYYiGp9zVy9I282HpeNDS2ZRURamFi8sQEDXpxZ1EJbOlykfeWl7Gxqh7UWU5Zv9T7bQlaLjkTCaxEoR4kKSeaqfJksfaTbuGZ7E5pbo8dOF4pcuGGX2EoaMttSY2s7uyiJkr+TNLV2YMH65LyUrx5Rdm+DWakU0jua2rzPdMWW3ZH3LE4mMdfq8x0ni2i+YycXyIU9IlghjXmGEaGIeeF8GnzuHe0eY77PGevIIXY0tbHnm7RcVkQ6zvvpmx86EqX7mPboFl2W+q6RJqZhb23g8cd9t1d6lJPTi0jWUExZgHzMWL0js9ay4OfvOHD3N2RsWC1QzexzBsCDAOZZa28jPw0EcGXq85UAXq1020qFjgmlul1Z+DvkWKe2g+/dp7UNRszzC0UteWKNCmUZKjTM9+heeCKgE5Gb/MDnFw74BZ568l/Nh2Tu3MLUeHE1a6/NTApQNw6eFxWYnPs0mwgCnGAvvb30ea2KFBrOWvcsZMqBpB90dLu0tfX+sUvFRfRom3yubMZEC/z6EiU0NLdlMnUVPm/077+8Pg/PTF6Vt8Bzof25RV1zW4f4mGluHboAA2esxVfvnYBjfz848ltreyISZ+GeK01HAnmVBED4emUUbnzlFAcu6XIHz0xexS7wpZeSLmobF9pPH5uwQlQfCeDHDqlmnVpJQzw73zGkIgLdjqvT0538xrWauyT66Lsz53J/ktymbt3kY6fk3nTvZlj3Kp/reIi30XeMDiu3FPm2cy2jdM6KY1GxsGVdE/z0qaz1n1ogi0mP/cOUO7JLHL15ImFLdlebuFQmUHdGqmkpugDANwFcZIx5N/Xv0wBuAnCJMWYRgItTf9cVS0kg2+szSwvY29HU5nWfWLMtuljzV+bOfu7R3WSKrFWC6Z5kC1RDzo1XNHA1XwB3PqQTeeg4IQAYxxQhzEe+2AipH7GPiJBhswv8tTuaI0d279KfSfpXVvEWY4KhfdiVRYrNTuXuH7equPQydjbld6UzxqBRmFbWXSqkq7W/OTfqtuiLlUlYmykeyN3/OEHUDS3tXk3lQ28vw59fz1+sciRxd2pPJLyCuttet9ZPuXCFbdeCSqEKlj698rtAFdNNpTEJvmfpfi9557glsgHw0nR/7Gc0UQZRHMR4199xFlRv5csoGpNxizaL3OfWkcLmyd+yP7qJWnxuvpE4jZyTFW5DcrPsF9278XFYaYvkROKuzgkBrhuym1ghwSiA3lq0GZ++c1zs2DzfHNuRsJnMeXGZszbqzTCYJFPxJXQp/GqGk4rcI9Gxw417liJNcQ8k104hkuNwuJ49PT3JMzjqVTldzexzb1lrjbX2TGvt2al/g621W6y1n7DWnmitvdhaW1w57xrg/rEy/0luAkvzr5GLvYO2OzBxPtRpenbvhr94FjlxOvHijbvYWinpxZ/Ltkj2n+iJZ67KDorUn9y9Xp+lKJ3Mohq4cVD5oIkGbhg0L2cyk5ij2bo95PMqYQYyoHDGrzTSRW10UZL9TIvr7SzgApKPGSXUkIi49Hk6fM6C1Ouu4z9PTnyD591y437uG5N/7EhY4O3FycVmLaaLHcbU1XDvs7QGSKmTqru7r7SBi09Ib2xpj1yLrwQCkMxiJ+FveTOP5Y517kKREnLxkXPpnCuqZ4Hq1r1qLrKcQc55yOd563Z6m1Qo4U8aNx6Gvt9uanmvAObM3hL7SCGLeFqZOnXFtkwfXL5ld6TP0SO4CYzcPkevxa3vNOClmZi7bmdsNyvfonx3awduHbYw/z6p9sxes4O1WlILneuaFqerW8ejb2rg8iPW89mlqbUD/QcMwsdvGZXzWzHKrBP+MARXPjzJ+ztXyysuHz0pf9x+R8KWJZthNal6ooWuzAZmUk3jFn+jfthuEgHfkDuZJGvot8+efu1kjCGnuT2Bphgpvh1jRoTJnuQSnIaG8stni4upCIpA83vhraMz2ZSA3IxRLzMa3TScNYku6lg3ONKme93FODN/u0H2PnzaRDopbWlsldcXEcL14lBF+YDiLVz5cAWGtZ5FCt0uX7aq7HbRv+mixy0sKWHfPfnA8TRcNs24Sk23CHWxzHcUFFy9KIlgsXDDrsi1TFle+uJqoEfB4DbnF89Ex7RH3l6G/gMG5Ywdvj7JJcPhzs1Z3X3zxTtOYp5SXfB6OAOELyFDXKKJFrKf2zusV3HiU3rMXuNXinXvZsSrenp4usjNtURleWN29H0JmKAxB3oZVEkzssCzmbt2Jz5711v48r/He/vFGUfsl/n8nUeii/9oanUqwHIZTKN/T1yW3zWsHAlhKL9+PvkOL3cEvTjzX956jin+9NqcWL4mdH5w74RPoL93zJKMsq6zoEJRGZC61NAB1KexcTtn1GoU/W3m6vzaRKpR+vCJB4ksShyuiTjOCxhx42LOS9/F3a1+94BSaGxpRyJhg2SV8d5b8suulvZI6tdCZ93V0o5nJ6+MagyZmy4dZGmb2jr8rcjR6glvk+R2diRsjoC3qaEF7/3zsJxkByHSyT/y9vLM51KfNtccd0HiO1eOK6FwOylUCFy6OSsgu9Ym36vkZnakSPuZ+576dnMVQKUWve0uiGdME9X2MoJAUS478aF1Z/Ld5+tfS1r76dje3OYv/Ly5oZjaW/ktJ+m4q/z7ZD+7iRz87m6yO7iPI5g/MXGFZ0sZ3/5Q/8jfPuuxMcAmT8KMOEmS5qzdGUvxyI71TudYv6M5c/9bSVwJ5zpKcWsf+qCWIs7yQt9pY4BP/zOZVXPpJn9CnOP67ZP57NbU8d093t3bskJEmjjJQlzamXnUJzCHUK5RNuyMl+SFKlA5bxDqcskpGTfEdCWsNioUlRnput3V8mQPEP0z4ZmwgGy6bxdqjn7wrWWyBjFQc+mGHc3eInH5eG7KKtw9anF0IHAXhuQnOlz8c0S0AGQxfrg+GprbcNp1Q3HrsAUZn+5yUIr8dultY/C7F2dFJp8cLxdh1qQ4uBOqdGKPuKJ4pq2W9gScZEMYNX8jtu1uw0NOgH+Iq6JuSL5n4hZv9W3nCukUN62s11XPe4Qobu0fH9JH7wogFGnBX+m53Gv07Xfv6Ki10o1NKZY9ivGDF/rARLXT2e9dl7FSoYk+OKuwhc24275GiiK7fPjEg9jz0UumChs6xKaLleb7jRsTfM9BXL7A2Y6rPefbL5KsIaf+ULbt1Pti+NwNuPbVOchHnLHo509PjzUP0PYWylJ2xQPv4KdPTUNreyKSMMPNOpq2PrnHe53JTEhZSxQW3HOMlGJwXQ69rol+JPFkOftAJvDcX6Ccg4RtjFvgyhhuz9udxFOhY4kKlVvJh1vzy0fIWnKVRIWiMiOtk0MX+DQLmDvZ0IWmJLMbkJtFx7dAc93WfJYTqj1bv7M5EhhaiN++MBO3DF0QGfhcN0LqEsJpUUaSTHq+VNOFSAt4r767NlaAqNTkzrqhML/t2N2WcamiGahcgXClk93NB41XiiuoScflaG2i/Nt0JBI5z5grMlkqEouAm+mL3iealYfLCLbIqdbut86673f+7dzJ0Yf7TH33ncusJbWYSjWc7kTu22+BI1hQjadUKKS4qX25/i4V9KPHyF7Hwg3yTFMS6ILCvS9ue045rA8A4MvvO6LkJC1AtBAo7Z+ubDNsTv4AeJdePfMvM6TKtNzFdJxnRb53njX961WSsVDq8eEeg8PNGOvjuSnZ+lb06psdV/XInTEGq1MxpDn9meogrc1YGK8bGBX6pPfWbYcPbijx/cQp9Xzv6eZdreJFuC+pSIjYmDj6SG4sdgugx6m7yD1TaXxVNAuw7LwhlNbVQIWiMsOZUym0OChdnLtuTfSv/ffaQ3TsHM2YZ7thTiYsn++tm/UuDrRJbvpaGjPBZcqjwtkbs0srVLdme5OoYGchfAMQZ1Xgxg76DOih3RgOep/oIsJtDnUjiDtk0WvkNOSSMbGlPeFPOFIGqSgRY3CnE/EQYT/b3eZY18i5IpkXnTbMWpPfHSHE/ELPFdqaKD0v4E9CwC0Obnszf/A2h1Rp5AbUc7daGmNSKuJU7ciud91sZBROKbNhZ7PIbdMVZqlFlbtnvr4b12uh1FfBFcbE4wDZbrETqykVJqRa9nuI1ZTu4yos3Pph6fWCVDjOscJJFV4xlIFi93TO6mPzf162uRE3Dp5fcB8OX/hBMceLo5TovUd372/jnXgd6bXs26tn0ftwSJSJQLL+Xhrp2rfWUKGozNCBf4ongQAQlaq5xYHP35tjL+alowOue1rfIHbq4X1E5+Wgg8dYT4Y6gPdxpgN6EFNtjNHD57Lo8ufX8mf8A/hBhibW4AuqZj+3dGQnfc7SyEGfzyKn3gK1WnD+y5JzrdiyO2ex5cuCJ7VMsIUbSxynpensc8+T/WI3oyH31haJaZEsp8ApvZdum+Z6Mqm5AfUUbkHlcynhYmAisQ6QL7SjQgL5LNw/NJyrI3WNWrrJP069tWizN5061Uy7BWSPOWjvzGeuf/qenXTRdPQBe0f+LvUdfnrSqugXMY7HZQjdwVh1uT7uheziZpwbTYuxC2NO6TjqbiYWdsgzXeEpXgpEk0RIXYqlCht376nesTm6pW+tMIlZn1FcZXGcBA3RWCv/9f7kwhMif9PnIy38HUI0oe8wd7m0PEYxxbNrCRWKKgiXrpkKBlyBOjq/SBUvbiVt2qm3NmZfTk4Yo8TVMscZPFrb/ftE3N1CLPJi7OMKbRGNCrnerVzhROGJXa2gD+pK6AZ3RuIAhM/DXVBRQZCbRKVWGffR0XgKSqzCfc4+cRZUdB83hbYPacr0Vid9qm8/rlgv5VHHgkihl+7WjolmdQrLdscthR6fTpzcuMK93tTViOK6tNHDPz9lNfk+enQu/TUNHqZ7VdDwFrF0/PGV2ZnPbl+npRK4gGjqZZizSHbq9lDOPmr/7LmZ9sZJLkCv5QPHHRBtU+AsYe3SICXaBmbyfYUs/qX9gnMlpAqqCYGLaubGV8n2o4tkzk2KKiZcbwl6LpreXhpT5Lq7U8PwFiJ0uNdUKC6rEG4mSHpd0r5Oray5hYCzx9izh98FeL0wkQGrJETx4z77/pGfuLVbLaNCUQWRzpucNsnnD8ueV3hid4Cc7IkVKpR20wfNJCOtn8NZgKjGL64vfanzKzefNkQqcfu3k9YHeu/R+xfeyMF1UZFqfKTwbjMyq6avf66PmUVHSqkCEsfJh0atqZGsZeSCXW1anMU1HQekGX9uHBJ1NZkhdB1xziza6h/DokIuvReNLdnr55QynDbVF9PoHo/GgNHFQEcimnqZiy2gmtC4MVWlQheh01Zuz/SZB8Yti1qvmObtJDFa3NhJx4s9eviXC9x74RsjxcKNcyFunaFSuXVYfiWMi9tnor9l4WIN/04UPrTPNTLZ4cRjAtnQvbXNHvdtLukEB718V+kqhd7PZWRtwCdNyO7jpqOn7ztNFnKnk6CJhiqEmAPXRxQlUitX9sTu/E/b1GevnpHfXCWa5Pj0WXFrS67epM9tMfe8WUJk860GKhRVEuHgwWlMpQtN6fEobnaUZybn18AOFdapyYVYToSab85N4dTDsgvPSroDUVzf8sjxIuOX/+C+OBIXriibdNCKM1Dx7micpYh+Lv68rltlnCHWDZam7oh04tjCZGOLwwtTo5kMadtpV81NyV18R57M1MuhC/cFTJyK1KqXiCFUu/12KXlnooH8MrdhF58VzV0AcK6epU/f/ra3EalAmhqZwy1oSftMxDWKGRSbPdpt15uBCmBsNj+uz5S48gxhhKO34pxj+kZ+k8aSUFzPP9/4y8XT0Xo1XN8Xe2aQk7lzOa1/xpV28Hk6uNBnyjmYRJVB/t9odjhWKCL7uNa1bpG+n/3ejc9zXRAlcG6qUkGFIhUs9nZCH/7r/gmyY9A+SI7opqOXtmnN9t2i7WjG0OXC9O61hgpFFUTqTiwXikptURTp5NB3b3+CB3fCpmwTZtCiSAOO4zKduJXEcfNocwZE+kzoApyzBgUJoqefmeO9tbhwvYa453VjDmhflaZ65VJFx2kTl12H3qe/vM7EfAmfz04mQ5ovkD9On3PhMrNZZqEUh13CdN0UN+1rh2cMk7rvutC95pFFPZe1zSXOul3aWnpsX2HqYpDWb5LGHFC++WC0WCaNA+npWIomLs1eC9eP4whFYazY+Q9y0iH75P2+GDqELndTVjBxxOT58EKRvF1prnllVuRvWvB2+srsnMcJzi9N8xcRp8o1zrWX6xc0VnUx+cxnn8viuu3RWFepcsnNfOujJUaBeg5W8cQoqOh6yJewBogqouavy+7TmynGzb2n/xi2ULQdvU8hyr9UAxWKKoj0RWUVciVq3+NCNZzcWVdv9y+8vnbvBO9vcfBp3zlcTe3Pn55e9Hlp8VouReYiYRV5sRcJewwykMoOJz4vq6kkx5jnxsyR37j6DRTOGhYHqTtICF99zk3KlyCFm9ikfO/RKZnPrtWICuMXnMDXqsnA3DLaE+KOPjSdL100sZYi8plb7FONbjHDo0+pwAULH7BPVjlUyZgiaXwe6+YsbC9VUriWIuqWxC/yPE0QtuGYA/cuvFEBOOtNHE1/bhxN/ovkhGC6R1yFQARyQ915jirD6G9rtvmLOHNKBXr5bibUyHbk1nJlMzj3weh5syd2FV7FKEHSSIUdqYU3Tg0/F2mMEhdaMHhWVglJ4wl7Ohk5qRL79CP28x6PzstseRHS3jixerWACkUVRDrucQNkG5PO10ff3j0Lb1SA1WTw5LLFubVBfIQQ5+hCc/i8Dd7tqLnctWZEjyc7Lx1kQsQKSQdS6SJCmp48xHkjPt6OO0NoVz3pdnH8n9lzSe+TcKVJFwBu5iZ6r12feQlrnP4dxxL16ITlou149w3heclm7670u5HSw33/sSmR34IIJOQEoxdkx7e/OuUCKPsSrau05g6XmUwKd2fjxaT5f6PvsLugkrbJh1skmUIT08R9vr7rchd1bnZNH1SYdxUgPnelnEx3HvgkI/7ffGUkOCMhbZ+7f6Q4sf8QsVJyT2Peb9peTgChp73wPf1EbeDgroNaZCXFXwH5GoI7Ly1Sz8aXc8cXzr00REIqmEvf9Q5Nya0UQuobzJm06UKbW3RS4Ylzd6N8pEDVcwlSwS908DFXPFG6OKdbcanA6Xbu4EYXg/OZbIMUcfkGmcEmdiHb6PGyR3xswgrvdlQZ5KbYpdfVp1fpgrlc2LF5P+ceTyqAiTbjj0E+c6mI6bkWCxdr7HnJ8R5jNLqU56f6F3J0bOLvrehUkSNw6e1pjBYVWoB4MSdu++if1OLJ9X26SKZZ4FzoGPHLZ9/1bieNa3PdJam1OlKjTHQ0HmoR4bKixskMyblGP07ue9z3z+eyGjeBy81vZJOTSIspc1DlCLs2iNHBQ8+vcY+/316ycZ/24T+87H+X6IPk+qMU7io++8+3Mp+lySSkd53L2EeT5XRnlMzcO0eTz4iLJAdYu9Gf2jTRglIQqaUoQKIF6jc8bpEsjsTdLk6XlmZkun148cUYXUJoZXxcwyxyOBdG+jdnjo4eT2qxkUlFbUKztfS2cClM6SEaHA0fvRfyjIqyNvFasuxnVgAhnzltrLj3CAOEQ7i9xvHXbhTGA63a6remSpch0pof0lvBZfSawiSaoEg139Kq8Ve/nI3b4Ao/PzreL1hF2yDaDL96boazHxGKyEUGEebJMbh5KfTyR2qN56BCO63xxnk6cNBjPDlxZeS3N4mngrS9A2eszXze0ugX1KSL1ZemZRUHXB8W30/mvNK+evj+e4m2k8Zo0Wd6x/BFzJYyuHtBY6XekbpXSy1ozA2k8bfc2oBbD1B3SZpsiHe9jZeQi0IFujieDrWACkUVRLqgcOt6UOjLdOLB/oDRXS0yTRY3uMXJ0iI1wcbJ+OMSx383jtk/57x0AeWM5YNnZV3XpLVlQmSkaiaxD3EsYzm/CSe9VWSAfMhZqIstMbJTiY89fkl2QuAW0/QQIVz6OY3cjqZsX+AeT8R9hWkTlxiCQo8RIn6JwruOysaOIIkmhKnvYyTxYuGy+VGk5QdiFfZEdE6gNZa4xB8RixJzvXQc5Mb20PGtY4jgEvfIzxHXoNlM7Skp9BrdceUJYtmS9jMaAP+pO8aV1jhEFaF8fKPseK7702mkaLu0xIJ0LuIsJ5TwYdSyA0rncrFrWQArividE24nLbb60Nt+hRzt+iHWNdVAhaIKIrWivEY0SC60hsYph/Xxbrd+h2xREifIlKOC8cZiIlp6zteabDdjlX8SHUxidu4ds6SUpgEA/v6Gv04GbdM7S/zaKlqXIcQCRXoImp7d1QxFCsUyx3AL1EkYBruRSQAAIABJREFUtcCv7aWuozc59XgiCNtH4eIquDoP949dmvnMTYhusd2QSF1ZOGhwM70K974Enq/FcDWG+Bio7Gex8CTsNSEEbg66oFxDxgHqnsWm02agfZVPmS47Xk4yFg/0GXCWHe55z1mbPVcc9z4X7r2VauMpNLkLdx1xXOHizgF79cymgH7sHb+FU17PKLvduU4q9Mh2ARR5FOk73NQq9aoIK7RxyrrI8ZjfRs6T1YuUzsNSS9Hbi/3rkBAujdVGhaI6YxDJKuIGVVO4vPrlhNNOhkY6V9CBmU20QIYMTsuxW6gBGTTTL9xKoZc4baXMTUia9EVa6ZqDLpTcYFRp7Rv5MJo9CGeVoefiLBbSa6T3qVeP7v7tmGPQIONKvpv0XnzwuANF23HQ+07vS5ujVZYuXkJbr7iYHYq7CJMWOKS411wtaNtplij6vLlAcbcWSvTYMhdY6SKcusVx0MMNZJSEz0/xx7/ROJ0Q4Q3VKkb5kyenFb0PZ3np1dP/vCmuwpRe/1TpXEQe5AG9/bHN4xmFH0WcTVR4vD++ysQvRc4r2kzcPq5UhPS8UnfoccIyHCES1tS/SKRCUUUJ0WGiixL/dlJzdGio33W5kQ5AO5uyg4ebuSoOF596iGg7afY5DisULGIdm/lNugCgA6mbdpsegivCGwfelSf/Z5chxOLHvZv0XnCLS+nzkWakCg036UkXtVTD+Ytn/AKI9N28I0BsIUUqZLmLOmrBCP2eSbXRUhcdF2oduoFkyzv2oN6i/Y/o64/7oAqWMYzFRjrdPM4kroiDNOFBCOu5NNYsdHr2GYwgedQB+Z/dOmYenr8+njWarilo6n83ZTq9fNovhs31Z4jlMhFSpE9x2FxZBlYuXpYi7d/S9oVYn0m7NNd/KJsCFzCvV1QoqiBc2mgptCp76EVtCILUWyD06unvomcdtb/oGFKffumIxmlWKVxRzTjwMUA272eOtxkNkrRoLpckgWrjNwqL5HFuJFQe4WvaZM/LvQe/fykbKM+5tlLhiZvMpJanOEU1Q8Bdo1RTyyWuoNBaG4fv18t/vAoqb+jluxnsKHGFEx8vkgB4DqkVRXp8zto9RxhjQ4WJu0Yu9m8njh0J7K7NTDc02Ufc5AoUaYrh0EJ1IxOwfs7R+V3SuHGPpmHmeM8h+3qPySXdoOPMXkKrVOiYIqkrmHSulFr3pe0TJ26oYFHk8QEKu0szLNcyKhRVEE5TIuULZx+e+cy90NUy9YcWirjLuFRosXmYCQwsJz1i+vFTIoXcmOcdqaEhfPTXvjrH+1uIWDMuoxKFNvcJxo+dWqK4SZn2/bjB65SWGEksOKQa5xBUy8GLJmk56gB/8c03A4yJoQkRfxKH0MkKuMU0TffOJ1qQnUvqDiTFZwFxkVrj4wqcFDe7Zr0ija3b01FIUoG2ifFYiTNGSrPPzVoje47bm2T9IvQySfoOT2dqNlG4/h1nuBi90B+HFEKg6QQykQpFlSTEguqovtkFBnc0aSYRKXLLU2ChKMQiNHAQp3Qwki7I99/bHwB/25tZ9yLuMh4nwkQlEy1wDBcGglJefVcWhyXNhCW16oVAnCK+Tus3APJJ75XpazKfv3D2EWVqTefihSkyi5KUMMkFZItVaaZSadeXLtCenrSy8EaorJKwku936PmW4maI/cr7jsy7HTffSOci6fORuseu3S7zTBBnSKvSYp8tDRJD5cUJY2H6Uv1LRSoU1Rm0Bs2RjC/4s5PDTrDUEsEROvlICPca6SGkmZHE6YaF55X6xZczxbWLdDILnWVMmkL7NSaJxbQVJDWt8Lxc0pLQSOPz564tPRNdM7EWHM1YbKRwQe8UWoiV1vOpB7YFKMwZB67+Rxy4hWa0CC9zDGFfdeMJfXBzFkXqpimlkm6ad43yuxmGJo4CjFv7cnElcRRM0ttevZTcMuTueGVuCCF0lw5RLFwtRUrFeXBc1hXspIP39W53fD9ZkK38Ja497bZYMy/cUDoRSxcAod1hQliyzhbGYVXLhYgn2yYuRoBOsJWslRDaUrR8iywImOOvg7OB93FSn7twsTi1Tk12aYI0m5QUrpvRtQsnPEnHgd579hBtx2WNpLQFjruTKp5CELrMBYfUsi5FqvCj0HIQLkNmr/P+Rjn9cFmhc2liltDz18B31xTeCPHuX1yeIgWEP3pSv5KPFyLmvTbXDcWhQlGdIS4iJuybjcJF47x1ssD7B0g9llohtHDy4lTZABl6fNhHuPA4aB9/6lOxYCXernKuetT0X8lFTujnKC9sGpbOEARbCrU+XYdOT84l9KCC0CImM6TUrYmr30V5Z+nWwhsVcV6leLgnRYuPu8QZB3cyiXMonAs5ZfkWmTU1dNzmWmFW3fuqtP45od8+VTmvS4iMu9VGhaLAlFtSlh5fmuWHZp36yIkHebcbOV8WHzJjdemVw6VI77TUAiQVntbvlA2QoQdmaVrrPr38E8wCYTpW6b2Qrl0WBTDNU/N+CKuHlBah5rdN+M5NXCZbGIYW5rsLF66dlc6gxSyGO0cs8v5GE7hsZSzfG4WxQqFvbSWTkXQ14sqbN3KFsD1IhdsQSagoXU2mDqGcVJKoUNRJkbpkvzA1bOxRJXl0/HLRdlJ/ZelitVpItTA0Fa2LNDZMPKkEGIulA/oIIphzmbVCG0Sk78gjby8Pe+LQ85zOm12K3cw7MmVFdoz4+xsLvNtJ4wxCdy1p+muleOK4eH3yNFmmV5dq1UuspAtjLaA6hHCoUFRn0EHm18/P8G4XRysaWjNdbqRCTIgAwjj0rmDms9CIEyjoSjsDV2MpDuMWlV43QslSyfiyShFXASB1m5YSeuqo1mK6FpAW3a0ke+8hc912CdEv9hW6jXdl1N00HAWFImPMwcaYLxljfmqM+a4x5nxjjApTHsotV0jjAtx0mj6iRT9l2ykyDttPlmmpFpEKO1sDF7qsZw5jipTGYa4wG6IiQ2olrSd+/LHjY+0X2hATWjnSlRd5B/T2x4RWi5eny+JoXUKsGzpLfahyEkKhHaKmX2fAK9wYYy40xgwFMAjAZQAOA3AqgGsAzDLG/MkY06eUkxtjHjLGbDTGzCbfHWCMedMYsyj1f/6SzV2U0NacrqyRKzf17Bffq4fMyrVkU+kZ0kIbmw7ed8+wBxRSaiIDLkFGCGiabKVrE1rJFXqoa2WSRIQuEF5rdCYFpC4vKkOIdeFeZfRsObAGBX0fnMXn0wB+YK09z1p7lbX2Gmvtb6y1nwdwFoDpAC4p8fyPAPiU890AACOstScCGJH6u24o9xgQerykLiX15j5XLY4TujfUc5HOihY9DXy8nt2rY8gu9f0p9+t3+5uydLZK/RC3y9TzWN/ZrUid6eoGzZKl5FZKI8g7UcaOt6WxFTuqVP+tWLyrB2vt/1lr85aLtta2W2tfsda+WMrJrbVjAbiBIV8A8Gjq86MAvljKORQeGozLzZM+d4tePbueJ6W47lGdTd6fP+vwzOdKNj281ro6972tRJ+k8itU6qs/SglRlLarEdq1V5p6WSkMLT1Q73R2AbZW2BIgFXa53RQ3NMiy9lYbzn3uV8aY7+X5/nvGmF+WsU2HWGvT6oX1APKmPTHGXGWMmWKMmbJpU+0UFCx7Su4yLp24pvuKZR7YuzquStVE6hZXz9rYSvL+4w4Mery3FlcnQUGpxe86q9BSbvrWkWtGaOJ2mdCumtWqz6LUJ6HjL7s6I4QlU5TCcGr+/wbwWJ7vHwfw3fI0J4pNrhLyDvvW2vuttedaa8/t16/0ar71gq6bqo+wHE1du89VUqDj6irFoVbSsV5wQnHCXtktRWU+frWYsarzaNaL5ZnJeZ05CtLa3ll7g1IPdPa4MCWXelm7ckJRD2ttjk3cWtsKvihyqWwwxhwGAKn/60oELvdzlxaSjEMcK1RX1G5Lr7neEi3Q1lYyjXlnTev99uIthTcilFuIrrPuqAjYHtNPv41JZFBrnHnkftVuQl1wxP71k+1Ux6KuR73M85xQ1M0Yk+O6lu+7wAwEcGXq85UAXi3z+ZQUdWzYqChrd8h8Y+vZnzpuCtY4hJ4gTejqrRWi3L2lqc1fzFPpWrRLzd01gLS8RFfnuH61V99IUdLUigdHITih6BYAg4wxHzPG7Jv693EArwO4NcTJjTFPA5gA4D3GmNWpGKabAFxijFkE4OLU33VDPWtA4lh96vhyy049C0WV5JHxy6vdhNpAu4tSIUpNCqLUHvVU7Lkreph0dW4ZuqDaTRDhLRVsrX3MGLMJwJ8BnI7klD0HwLXW2iEhTm6tvcLz0ydCHF8pjmqu4U8+dF/MX99QvQaUgXrLPlctpq7YFvR4a7Y1BT1epdDeolSKQ/tooLtSPXSs63qEyJBXCdh8ytbaIdbaj1lrD7TWHpT6HEQg6qxU02/y/GMPKGn/d2MELIdS+BxY5sKV1UCVYdVh/c76SP3potrTsJxxhMai+FgndAFWlHKg/a/r0a1OqrdwKbmvMcZ4V9nGmIuMMZ8tT7OUWNTxmqozrgd3lTnvf2jmrlXf/WrSCV+BqjJb+7OXUtPHK4qiFEO3Oon19brPAZgF4DVjTDOAaQA2AegF4EQAZwMYDuBvZW9hnVHNxX016uKEsox1RqGo3liyqbHaTejS6DsQFr2fiqIotUG9JEzhYopeBfCqMeZEABcAOAzATgBPALjKWlufjvudmGqsATbsbAlynHpJ16go5ULfAUVRFEWpHpylCABgrV0EYFEF2qKUSD3HJNRx0xUlCM1t9ZGyVFEURVE6I3US+qRIqGe5YuKyrdVugqIoiqIoXZSjDqifArhKeVChKDDViOtJo9YWRVEURVGU4tE1lKJCUWDGLqxeATV9nxVFURRFUYpHhSKloFBkjDnJGDPCGDM79feZxphryt+0+qS1o3pxATNi1BlSFEVRFEXp6tRbGQ0lPBJL0QMAfg+gDQCstTMBfL2cjapn6jnZgaIoiqIoSlekmuEPSm0gEYr2ttZOcr5TcVpRFEVRFEXpFNRHeVGlnEiEos3GmOORClkxxnwVwLqytkpRFEVRFEVRKkSDus91eQrWKQLwUwD3AzjZGLMGwDIA/13WVtUxan1VFEVRFEWpL3T9prBCkTGmO4CfWGsvNsb0BtDNWttQmabVJ1qVXlEURVEURVHqC1YostZ2GGM+nPrcWJkm1TeqaVAURVGqhTE6DymKosRB4j433RgzEMDzADKCkbX2pbK1qo5J6GSkKIqiVAkViBRFUeIhEYp6AdgC4CLynQWgQpGiKIqiKIqiKHVPQaHIWvudSjSks6B1ihRFURRFURSlvigoFBljHgZyswdYa79blhbVOSoSKYqi8HQz6mqsJPnBR47FA+OWVbsZFeOMI/bDrDU7qt0MRVHyIHGfe5187gXgSwDWlqc5nQCd6BVFUVhUIFLS9OrZvdpNqChGK4QqSs0icZ97kf5tjHkawFtla1Gdoym5FUVRFEWG6WJSQle7XkWpJ7rF2OdEAAeHbkhnQUOKFEVRFEVGVxMRZqzaXu0mKIriQRJT1ICoU9h6AL8rW4vqnNdmqmehoiiKokh4YerqajdBURQFgMx9bt9KNKSz8PbiLdVugqIoiqLUBW0diWo3QVEUBYDAfc4YM0LynaIoiqIoSjF8/byjqt0ERVEUAIylyBjTC8DeAA4yxvRF1vW3D4AjKtA2RVEURVE6MZt2tVS7CYqiKAB497kfAvglgMMBTEVWKNoJ4F9lbpeiKIqiKJ0czcamKEqt4HWfs9beaa09FsBvrLXHWWuPTf07y1qrQpGiKIqiKEqNctxBvavdhGCcccR+1W6CEoPzjz2g2k0oioIxRdbau4wxpxtjLjfGfCv9r9wNM8Z8yhizwBiz2BgzoNznUxRFURSlssxbtzPo8Y7Yf6+gx6tnunXrPFa4vfboWkV+Owvf+uAx1W5CUUgSLVwH4K7UvwsB/B3A58vZKGNMdwB3A7gMwKkArjDGnFrOcyqKoiiKUll2NLUFPV7f3j2DHq+e2bdXwQTDilJWutWZe6ykeOtXAXwCwHpr7XcAnAWg3HbM8wEsttYutda2AngGwBfKfE5FURRFUSpI6JTccQqon33U/kHbUCucdnifajchGJOWba12EyLs1bNrW66OFbpm1pdIJBOKmqy1CQDtxpg+ADYCKHcOzSMArCJ/r4aT8c4Yc5UxZooxZsqmTZvK3BylFDrTwKwoiqKEw9TAsqnOlNliWtu1BlS5sIghfXcijjlwb9F29fZuSYSiKcaY/QE8gGQWumkAJpS1VQKstfdba8+11p7br1+/ajdHYYijuVNknNe/b7WboChKmbjmM6dUuwmx2aOHZHmhdDVC9IsL36NrvmojX9fVl1TE9k6TzJV5o7V2u7X2XgCXALgy5UZXTtYgao06MvWdUofUm6agnjikT6/I31d/+uQqtURRKktXsEDv2QVcdELPD733LD6OprNOUbXo4vXZMw4r+RjH99snQEuUUui7tyx2r97Wf6xQZK21AAaTv5dba2eWvVXAZAAnGmOONcbsAeDrAAZW4LwV55TDOv/ErpQPt8ZHv333rFJLFKWy1FsAbxz26C67xsP361V4oxriq+ccmfkc+in+8KPHFb1PZ3Vm2GuP2ku08IX3HlF4owLst1f1k2nUogfMew7Zt2Ln6tt7D9F29TZOS+yY04wx55W9JQRrbTuAnwEYCmAegOestXMq2YZKUV/dJR61OHhUi3JnSK0F//wQXBVjYcNRC5OoEpY6m2tjceaRnTMBwLnHlM/td88eMutILVpRQlOLGblDtEn67vfuYmm8azHOKR171FOo4Kk2EqHo/QAmGGOWGGNmGmNmGWPKbi2y1g621p5krT3eWvvXcp+vWhwglLbrGelrevKhldNyVIvugWcp14TdWRaKBwe2eHWW+6LukVk6ySNlkS7ca28pBNx++dne3y444aDMZ9faXSpHHyALAL/0tEOybQjagtohjpa+T4A03lecf7T3t+4Bnre0z3SUUSNbi+nOa1EBbQAcdcBe+NyZh1e7KSIkQtEnARwP4CIAnwPw2dT/SgBqUYMduvidrcU3tUr06BY2+PiXF58U9Hgutdg/KeXUONciI+dvrHYTyk4tKkek6WdDK7n6C89bi1x4sj8YvhcR9i58z8FBz9u9TjTSpbBHd9k8EkcHF6LgKyeYVrKgbHndyWqvn1VypSUVuPdLKW7rZRVY8M2y1q5AMunBRanPuyX7KTJqseK0NC4l9OLlm3VW+TgOIR73h44/MPN5b8c9gA5UIRZoPYWTb7XYXxjs2VmYvnJ7tZsQG+lC7lRhAoXQFgYO6eLq1CrFiNbeLMJDH90hfQJbhZnf3PGynJQz+96X3yeLy4nzjoSIAUkwitBKxpj02zcba/erS8qrQIzDe48O6x5byfFH+hQP3rdXXbn1F3xrjTHXAfgdgN+nvuoJ4IlyNqor0bMGhSJpk6RWBG6ApHTWAnqUEELwDz92vPc3Ot+E6FnlnL/O73+A97fQxsXQl7FPjAxXIaiWto1TgOwpXPy97xjZ+81NoHQxWMmhs7m9Q7Tdcf3q17ITmpa2bI2ci0/xW4NC92luzKIWKjrGTIupbPjoSX5r2C8+cWKsY0roJXSrjDN+b21sLX4nhxamPlIIPZv8urIPuT1wkeAQc6P0EB8m7qYc133u1PiNUQDILD5fAvB5AI0AYK1dC6D2/BvqlEpqO6VI416kk5l0gcttV4O3KRbSySwuizbsynyW3jMufqect33PnqXPjl3OM7MGr/epH7xftJ1UQ8xttm57M9mu9gaF0K7H9Qx93vvvHbVa+57c188rvS48J1Rv3138gp+LHalWvZzLz83ep8+d5Y/VqJaG/plJK5lfA8QUCY9B54fQ48VFjNun1AIkHc4PZqypP7vwhMznclvhukRyEsE2ranU3BYAjDGqCgtIiD7cK8DiklLJxQZdkFfS5P7lAGlBKQftI3MBCTGorN622/vboFnrMp+lcRAHMm0v5yD7xbNLfwbS5oWWJaTB3KGpZHah84/NWvK4MeGcY/wWP4r0WXGbTVi6RbRdaGo9rewJAWInQqfzN2Ra4vRs9KePMZaXkw4pvTYNjdGSPlLu2R+2n18IjljtA3ef/Yjb8FcYV7pqeT83tfktqyEsvNJxkNYyC/0O3/Cl0zOfXa+ZZ676QObzFefLBP3ffuo9sdoR57Ie/na8hNKHktT/NT4kxkbyyjxnjLkPwP7GmB8AGA7ggfI2q+sQol995oywWT1Cu6Vww9f93zo38znBWYrCNQdAZV02KCHu7ZKNjaLzSt0bq5UI46yj9vP+Ric9zlWtWpaiz5xZegHCOFTyemkK1X0DuAtKtbvSxUslBRXpeyt9PB887sDCGxXBLz5xQuGNKoyJfJZaCf3bHdVXpojgusUXzipeEcMdr/eeMiXX7z4VNmuktOdXy5pqrX+RHyIDq7Q/UUE/9LqGxtsOuCz6fGla+ItOPgQ+6Hj+k49H3+GIMMUMLHHmhNOP8M+9Q37xEdExDt63vmqjSZEkWrgVwAsAXgRwEoBrrbV3lbthXYUQE/tnAy/QxBnHnJfxDOZF80FdEyq5OJfGOYUmxCTFBfBGFiLCc3HBx+WdU/0Hlz6eENaHeiJ0r+XedTo2nXRo6Vp6aTyd+JlW9KGGPVnoBCHdhVktuRiYcrqCVfKZhu4WvWMWQKUL9x8xcaClUotupCcdsg+O75d/zAix5hEfgmwo3efjMd4DLiFRGMsY91vxswJ3L3qQBr//WL8XwJUf6l/0eesBqXF1FoBxAMamPiuBqMHxDNd8Jl6wHjUZUzgBhNYs6Lu3P1saHUg/c0bltPTSejkxxujYfOREf9BlnEQLXKHUOM2Vuu1x0OvgNIturIKPGgzFiYU046PUp106OYaITQj9jpx5ZPFKmLiE1jJXK+sozVbtNuEXTnp/n1v2Ly8uPoGA+0zpQr6b57OL+B3mXPWEt/07F/TPfP7NJ/1Zy7j3opyPuLGlXbRdHKuMO37HuY5zjumLszyFh0PX6uOgiaykwuMNXzy98EYO3JG50/oER5fQSlzpE3CFvQNJRttinuM9//2+siYeCYkk+9z3AUwC8GUAXwXwjjHmu+VumFI9esd0lfHt197BCEXkxWJrcpD3L3RcBScUSLO+VNJiERV8okc8icQWSNvEabniaCH/9qUzRNtJXf/++Fm/kH5kX1lge4Lzzawjvi3UzklTd3NP9wJh35ci70qyDX99qd8HX9ovpIRIKvO/F2XdY+IUsOTiIKXrk4tOzgaHu4sa9xh9euW3ZkndZvYl+3PjyKeJpwN3GVJPAl+7i4Eeo1ePeHGgcRRg0kQdO5vbsufh2lB8E3LazcWccvTtnf85hFAMrtjSWHgjxEuLHqeWIHdNXN+Xjud8aEH5hMw+e0XXdPR+0rMWKmR7+hH71U3NNcnT/z8A77XWfttaeyWAc5BM0a0EoBYtRdImnXKYTGvNDUxSbQPdbN89S5/06Pz6vQ8fG/mtd4VqWfSIqzFjBsjDyaQqHSy5Adc3sXGEyCpH235g4IKYtUKcwPbQrjLc8SITYAXdmqRacC6T4ydODlsQVLog/8o5fsGFLhzipO4+kknuIX3XqZudO/ZKldFxxi13D/q3tH6VVDB1+wVtrrTl0nOdycRFxkmqc/WnTxFuWborqm/u5Z6VFGv9fbIfEbI4rweOiUu3iraj13/iwTKrTJyxjnVBZ/Y7g7V2Z/c8JnBiH6kL4/uOjhZHv/7zp+Xd7rrP5f++HpGMRlsANJC/G1LfKUGoPalIOij0CFBV2zcw93SqktMB9qqP+S07UhZuaPD+RifEcrq5lEMgjjeB+ZcAv78sO0mHrg4exGpWg++PlD4FtGv5CB13x2YFo/74Ac4lFehamJpA5x7T1/sb5Zsf7C/aTop72/t6YoL230smwIcuiizPwpi9EPfdcXvWl1KWKTf+KY77k7sI82VmO4c8X9d9L27X7x5xoYp3DB+cQBfH0iq1bEjdXuPE7+RaEEu7aZzliXPF5LpZu9DyT/v4B473Jzeh2US5q3XXJWkuPfVQ7z5HOglC4hQQPoEIdKcxxa2l/Yd7pvSnDuc++zxROlOqbskdXAxgojHm+lQh13cALDTG/MoY86vyNq/zU8n0lFLi1ACIu53v5TzJWYDTzaSaRY5mJmUoba/0ZY+zOHf3Of2I4qtR59w+z2KDg5tf9iIDeCXTQVfyXPXEwBlrgx6Pezepi1clg7m5d0nq2hunuZyQ6vr0f9CzwAqR5tlH6CdQaO5Ju7t80lnwneikxpZcirsNjQWkP/UlVuEj9t8rIhjFHRGMpx9zff+I/WUugnHdpnxIlR7ckU+QWkQ837tJO+K8S/Qq+Hgb/6/cnaCLdS62kMYEu2f65GnZrHClrsM45akr3J9ymHSez17j55laVBRx6ANzvbQLcsJnNC5Qdtp6QLK6XALgFWSf0KsAliFZwFWLuHo4n8naUfMIO/gxB8pMutzg5tM6unND6HdOOsFedrpfA0QJsWYUZ/1jzrVsU9bXWrrw2qMHozUin6sWlsPGHkkXyZ1j1N6yq/Rq83sSbeIWpnp9iLowceBc+qVWijhP+zsXRN1oLz4l64J3hhM0TvuTtGYVXWDE6Y4huvCFpOCku5BzF+TpP42JLnpoTbZ99uwhGme45+Z7N7/x/mPwP+8/xts+Kb5Tc26AtDhqXKSPi94b6RVGBb3ob98l/ThO4gpX5yh36SPHjjlX0EQy3DGiWWv9232IsdZRi1WkDwoFhrgcwhRi9RG65pVYYSqc9F1FST0jScn9J+5fJRpZj5TTf7XcSKX+EK5lvoBjVzPbjZkE4nDiwTJ5nhtUQxOijsvohZvoAUXwBQizB5EOkNKJQ5xRh9nsqwEWL1IO26/6dRlC9P0/fEa2yDlaqPSjmTrwAAAgAElEQVSQIm069x5Ij0EtEVLLshvnQ7WupzsuK3TcuvgUfx0SCn1/Qg/70n5B423cccSXQMEYvytY3949RfMF667j3Sf66sfNwPX1847OfKZZGfswSiipEiWE+26p44rbhlLdBU87LGp5OZxJ/sApBOKc+1eXZDP9XXKq/7365gePEW0XbY+sD4Z2yc5xHY3hiRO6gghtwU8+Hk0XT5srdVM89qAuJBQZY841xrxsjJlmjJmZ/leJxtUz8mxklZOKpJaISmrVxUH5Hk1lMVD3tIhbWAUtIHQBRV3Efn2JP+2rC/Xxd5/Uj8tYD0O+KJFtt7GhJX5jUsTJ4hUX6v8eIraHLlB9vuocbqyHNCFFnDsWRjspO8jFp/qTJEjbcQC5F9ICm3s6WcYiixJn20jwvnSsD6zYiRw7xlN1hRk3HiE7PplI22nphG7GiM4dR3+WDNaP/h0HunCPk5kuvtuebLvQrpT0cHGOfelpUSGDO8R7iGWHWkAisWtFtIFuy5XD6C7cTn5i2WZx+kKOUFmyO2LYwYN7PPnm/HxFebua+9yTAB4G8BUAnyP/FIZKVluXThbS/Pultvwb7z868je3gPRlkHJ3ofeTyzrFcUBvMmgzbWpi4o18SO8ZjZWiTdh/755BBGnqViBtE9d/Gkjq176Bs8CJ3xHWb192iBBCDG3vvgHS/tJEJcccGLVSSAT/A5znIb0XZx8lS1YQAmltii+RdNPvOcTvcx9HYcPtcymjZf7Acdm4oZxEC553gWudtB6PD7YmTvG6pYKuiNR97rA+WWsGdb+0FqKBhisaKyWupchXKDfEmFBJVyZaHJ2PZcr/2U337QbR+wi5likmyQA3BobWY0o9UULciTjHCJ1gRzqO5usjP/n4CVh+02diHa8ekAylm6y1A621y6y1K9L/yt6yOqSpNbuYFruKBOhL0vclRGabyHZ5vlv818vwV0f4ijOouoH2Ie4TVcZHMsxVUAvObRbcRC5sE7fYWLFld+bzlYEzevEuNWEHWSrEfPA4fxYiaarkC07wH4Ny+blHZj5/7ZwjI7+1tScynw/tE3WhET26mP3lpEOFrg7k+HGfx6HENYiL4aAubtwCP867yu0Sdf+J3tBzIpnuor/R90LcjhK7NJeVj3s+/hiGAkIR+ZxPO5xG8kyk9d64NsQdHz/mEcgammWp38uNtFsM/NkFZB//Ij7yG/n+LCZ9OIe0fZ86LRt/ayNjR5ZiBNufkbpeLnHi83iFRfZz3H5x7/+cE/n7zf/3Ubz0kw/ltkPYYOmtkhzu/zmFmaXjqFRw7kxIVsnXGWP+Y4y5whjz5fS/sresDqlWxqzQZ5W+jNQX+qB9kprTHt275bz0RziFFCVuPuVItEDbRd0oDu5T3lgRn6vNaUfEm6Qo7r2OaqPzt6EY6GM4lUkFGgeuTaHfJWpB4zTknDte9F7LbijNBHX5edH4p7nrdmY+u/F5vibyE6BQMK+gyy4902FMRi/6vDlhOZaFpQyKp5HzN2Y+05gGrtdGek+MRrV1JLy/tSf8v/med8EmpC7awF+zSvqextUklxpX8fXzjvKeuyOEpYh83sfJ/BUiRjRyvBiKt2hMqGj3nPa4FmkKvYXUE0MKd0Vc2voR8zYUfy7mZPSad7f6hSLuGP+/vTOPz6Oq9//nm6RJmq1pmrRpszRd0qRpmy5J043ue9NSoCxF1rIJlH2TAgKCSLl69V7vverF5bqLXHHhKqjo1YsbILIpCohQBfSHCAIiCLQ9vz+emSdnzjPnzJl5Zp4l+b5fr7zyPPPMnDkzc+ac8z3fTU0Y3TmhNp3nZ3XXkGAe5U0wpT/RNeO2hqH6qIt9VeWyRYm3RrK5HwtF/uwCMA/AJgyZzm1NslLDgTjUiZNiduyOWxMhJ/ZS7fFl1PDaNqhVtU10aYrsIk80ozi3HjvQHryTDws7hiIRzpo0JAhdvqnbs5+9b4L+N12iQjVM6xTL7NKy2r7eNjqeJXG8I3Fr7Y1RsrI8rzppklFPq3s+RhOqmO+Fx449hrJNea5s+yaT07eO89fp/fXWzNT7L8kTfrl6ahb6qZbvktfXw+oQD6bJ82N/0udd05lTmRJCzmurH/IoItUfauizKUmnLbpHr15uVPM5Xe3inu9FNXGSr9M2KIjZfM5fi2QSAt+5Yij3n1p2mzG6ovyO+EcvDNoWhVffeDt4J4U4UnlEbeuyP7d15DfNzTpSsTjQLUzIQqUxuaxSH1lgimPhoNiwaSULhRD9QoiThBC7nL9TEq/ZMGbXso70Z3MSLYO5iaUpXBTk05rseuX9VnXpbcYnKJoYm9dM7RC29trF6TdFgrLNUaHjxiPmhD9IQZ4MRXGuB5TJuVp+if/kRUUewE33Isp9sj1Gzd+gw3SXkowUtKC9XruftWmDVD9Tfgq1H/jwzvmBZatViCpUy/2Rp/yYox+pGmPPuTTnVYkimMv5h/qU5K9Lp/mbdfVNHuuph+xH09/hLcPrBK1HbgvRNF76Y0wCg8dfQqrDuBq9BkC+XtM71t5Q5Svghbk8kzAhT/iiTNB2r9abYEUVsmT/N2NEM+v3UbJgsEwx4Dk+4LuL6T7LgYdM19RjmWNHCJF+dkm4m0R5crK2ZUJdReyLxBWGOVmUU6lCuzteRgkXLwTwuVMHtL83avoC1hT581Mi6km8JsMMuSNQE4DaaimMzrOR2mq8DVzuVGqUxIfnxDAYyX4btiurJqHoJSknS2OttxM4Q1opi0KUATCJc3lWCeXtylApDxDyxEPtHKOsftoeYZ5s2a2+R8Fk8mPrwBzHuWTUnF82gRzicr69UpOHRO63ojbbldJiSS6Dz8jIt0n13dKh+j+t6dZrlDznMvym09jYkssIT0TeQAs6OhqrPc918dSUVjwu/0PZnHWt5TOQaWuoStc/w6ctwuuzaEqDdTRDW6I8VltTMJk4gsPYjt1dzUPCk9zPBx1t26eFCdjgx9fOXub53ilpsdVxybMAbbjvnTFowj3HxDhfEwDqR+sXQX78rjW+21ko8mcxgIeI6HEnHPcvOSR3MN5VQf1vtmX4/JgmjsmRbtCPOo8pi6gFSaP6FMUQyOAvrw2FgFbtla0Tp2rYf8DStl75XlfpvzI40BEt+S9pvqj35ZINQyZFcvNZ1eVtB1FaVq3mmlRMpmpLpukDGUSZXMoTheY6vcYiysQrDtRBPsp7Z9+vKN81JxujidoVBjkHlinbepxOxRllW7ZitQ6yuaN8j+wz0ut5yZA0V4f6vsgBBEz51KL24e64EnS4bNrc5OQ6mm/QstqfH9g6d8hCYLplbjkd6jsWZcJ36cYuzwq+fG+ijsLepMHhH5Z6GZ7+USpPDV3tWfQwzFdkNs7yJjOX3xl5sffYgTaUOau6Z6+W0kTENMeWn12U6Y+q1ZGDROiS0v/wklWR7RJkYdK6DOW6dNdp0+8LIbT9AEEf0TeqNrWYsRGKNgHoBLABQ/5EHJI7gL+/OeSsF3WF1DY0pG2zNbVvXUdoOoYijgjvXJHqJNcZ7PkPCmGMsBMFTxExv+uejl9BPpUaevnQef5mgaZoTzDcF52pjIocaEKunxpoIMpCkcm/TJ4sBZkP6sL4qlHcbJAvyyS09bZmP5lbNGVIoDUJAt5j7KLZyUQ1n4uC2g/YJqeWaTOaz9k1tHuffin0eaOM60R6X4ppTdknKjQFTbBlrdR/mgOEhC97XttYa7NA2yTeCzv8Q8GbfIrk67LOaWdANuW2NcfzRFIj/SJk1PmjmsLCBjnRbmb0OTt0wTNeMfjrLDQs1slmXUSE0hLCvr2DuEDy6XMj4NkunOlIUoGhu5/NYypj6WPH2eZZVM7lRtyLtjBkOo++wLctF3uHE4G9jBN+uw3AGufz6zbHjUQ8qy2yxlV9ybI0o1CPy6Uwbx3WWxMWFBgy0Rrjo879px29ADJfYpNg+aFj5lrVKUnzHXmQ2q0ISHNbh4Ir6LKNq9ery60RRJSkkvLEQyekxcFph0wJFYHLb/Jx5sppiUZPM5ms2r63HZLgu3n2RO1+8kqtKgBqV/Wk7dXl3omFbf6uKCacqtCyZ0sqSIgu3HGEE1jxzEvhQ2En3T/K5ZvCjsvIfZEsRNueB/Cu2lubU1mOGws7xqa16UHtytasT2e+pTuc4BVcDkScoMn9hazVimZhQRlCkoutj6SxdM3NUBchdD4gqTLsFhM1zQK/kaJiqqhm595gLMENwQ3O5AYnkY9R3QyMJCkUaVpkNv3IuWtS+dqu2daDSzaYFjyHUO+Hqx1TNZy6BSXPmnXEuh9k87lMiOgaAO8CsMfZNArA55Os1PBA7piiTeLinsQ3xpH5OQYzF1MRA84EIUxIbvk+qVHWZPzMtVxzqThvdakys75wvT76Vdx4NUVDqOaB8u2d3TJkDqSGFZUnDnWWJoa6yUblqNJI74J8zOWbuw172pZnd66o761usqGycZYhKIiF4HfeWq/f3gXr7BKlZpjPWR3j3cu9N1GHzO0JCt/5xOx479+2Pr1rwKr/URekZK2H6XDvQsTQ56Bomkf3t+HsVdNwXkACXrnPMQkaV2wJ9+6WlJDHfCfb6Zl6fNT5ns7szlYrbEL3HDO1wuE1g6aFRp3JnUrrWFMkumDUOsjtpbysxPoZy+2iwzL6o6k2smBhXMSOuCDX1VyLfXsHsWvZFGNABlsu3TgkWDWP8dfAe9tItMbO0ef8ORzAoQD+DgBCiD8CyM64dwQgt0fX+dR3P8NLZnr9orRVk+rbe97wZmsZnbb0OcNfx9nZb4WxJD3Z8trALrRcTR1nyJUgR55yO0E3B0OUzm6bZO+uToSrJfv1qnLdYKk/p23UP3Vw1GkzTMKiNziDvk62moikka/LdmVepmOcfhA1LUTIJodJBw2wKX6TooWS21l1lo7IQWR79e7KqYvwfNZ3bqpPgw2e0hJ4bFEcouVmO9ryWZn8Hm2FMZnVBv+5/QcFystKcNmm7kBfML93wT3n1t6hNlqn0RRpzefgnTSH0iSoBfmcKMhfYssc/7am5ozRhWTXPRLTgoCuXwnj22HbxKPlQssOY6TBENco34/FhmTcOl6M4NMnIDI0ZVFQr3LHAn9zcHU/t/0TeX2iVhsi/6bLMrlBGI47cFBo/Z6HKzZC0Vsi1VoFABBRcmGhhhFyQzP5C0TtgEpiWAVQauK7NSO2v24VyvDWySFMgaFJhN+1u9vU4uScSCq6FS+VOZIZm+v34g74cQ8Ehy9oCd5JQZ681FcZzCMsyzAJOHPb9L4z124bCjYZxdHSdETcJiZRAnCYfCBMMpYcjCTpSGBym5Y1eSbkd/AkKZeOGko+jmAFaU1RiPZhmvzbhoiPkopALtu40BS6ZLd8u/3kc7eFWHGPIvjrzmtb0j/ePuAtw2SeJz0S9VZ8eOd8PPHezb6/BdWpqrzMo82J6lOkq3uQpujcNZ1oaxjtiYJKBMycKEUqI8KnTl7oe7yaisJFv0hm0PKEmNTKfaLcdOIIyKSeK2yZGRYgEQfeMFq+Szd2ZcxBMrXl+nq4CzFlJSU4Y4Xedzgq7z+yN/2OyMRpuha1pAMHBdo1gSeGKza9zK1E9J8A6onodADfA/CJZKtV/MQyyba0BzahC/9ts7rgSwTzOXUSatOPhulrbZ025YnmtrmTcNH6GR41tIt1MkbN9q8/9JzV8VH8IwDzQFLiue/yMd79dIlEibwryH2T/TV0qpmdDX0dY73OuKFLiIcVnfpIXTrzQ8B+ANf5HKiYypNNPU1O9Drk1ewgM6kofZXNIWogjarysnQEMPWcPZPsBL9shfQokwOTIN9YU25dJ/ma1Qm+6X7aJI02PsMEXzQi7zvjfna3lJRQoCCrvgfu2FRTWWYdZcxkOuou7C1QclQFTTpnTqzDjy5bo12gmtqUGid02h01wqmLLGTZYmpj0xQrAK9fafiGEUfaCB1VMZgYAkEJZb3sXj0dHzpmnmcbkdc3zKTtff+Rc3HPnrUoLysJXKB46Or1eOTaDcZ9VEFS947Y+g7ZnCeqPDyhrjJRH95CxCbQwgcAfAXAbQC6AFwthPhwNicloqOI6FEiOkhE/cpve4joSScE+MZszpNPbLUXG3r0fgW2RIuBb4cuPGUQNh2r38vmmrO9Y1G79cTb2rFU+lxaQjhvbaevaYgpVLRN2a++8bZVR/LW/oOxdzhjq+UB3E5rJKPev2aNUG2a6DQpvmtdTv6G5rpKbaAJY53sdgsoY6gUNQKgZz/pZOpAaot9CGjbyfRQpVZZBjZQ79lph0zxLS9J/ARvXZ6gBsns1eiPqLllpjDZh86N7r/0/YtXanN4uPWJ0v+qE2mTSaeLbd8WdK44EcLbnq7e2oNjB9ojmTm6yD6ZHp8iw402+bpUjirFN889BB85boFnexQBmwAc1deGnQvb8LWzljnlp+pr8wyD6qrrp/38mFwTKtWs0rSw4zmXRniyPSYMbjjw3paUtYbfnQ/zNEz+mDaUlZBVMBsgNdbpxkGV+qpyrZloWHQyu9pGTNFeXVR3BE95hme6dNq4dOAok3XJcMIm0MJNQoi7hBCXCiEuEULcRUQ3ZXneXwE4AsDdyrl6AOwEMAupUOAfIaLCcGSwQNvoMvYb2qLaJ5uOczl71TRtZndVa/JOTVLSzPHA/w386HF92vqZy9OzaXYzeibW4axVmaro6ooyPH3jFuxePR3XbJuF4xa1474r1toXbsA0OYhz2mA9CaEhX6mg3Ceys7Op9KXTvKYeLv2acLgZVSLydLq6iYipDnWVo9J+dNOa9BMF29xQsRiHWj4S+dnJq5GuLHf7OcvwvYtWxFAje2QZXV3t1h/jveCk5sXmkP2ZJ13vLAKNrdInCTaVqfvpmP5Mu/x9ewfx9I1bPL5wtrfBfQemNdUY/fuqKkojmc+p6y7vP0ofQdNGyFbv9XJJG0qG/XSEERjka2mqrcCNR8zxXTQJK4MQYP3y7wgwV57dMiZjAcw09mrrRITR5aXYu6M3ncdrfF0lPnlSP/5DErrMfsSZzHI0pVHM50wnkJ93Ej7ztkXOdoQhY/MLUT/dtYy1jNoaxQzXdN4k6LBckFYXIf0w1bvHMPc4KEQ6amRVgfgUJ41Ny1jvsy3TADIEQojfCCEe9/lpO4BbhBBvCiGeBvAkgIFszlXomDoJ3UR558J2/NOR/oOoWpzOHjQzCox/HeJI4KhSX1WOO85fro0a43bklaNKccPhczDeMgs9EKARicEcMdtjPMcjtYp935VrA4NgXCAJRWbhzn/Fb/u88D5OJoImV8csTJnJzW4Zo71PJr+pgLOHPqLTSfx4iJPkUqcNDBJoe1vrA5NI2icitbsOua5qcl192fbnihYR0H97kOb7sk3duP+qdWmNcFjCru6r12a7YBG025FOrqzTDpkaKdCCWi9Zq/aZU/yHvDCGUJ84qR9fPH0RPnZ8n1c7G7aiFsStiXLNLonIE/1KvstXDc70HBOlDcu+QdmyduYEzyKPsY/2+SmoWdtqldXIZmYNom673fiSDUnpLm3bwbgadVFGKsNQuyjvuoqtJUppQB6/IDwCsc/vbgAFk8+7J1HxCLGi0wpFRHQWEf0SQBcRPSL9PQ3gkYTq0wLgGen7s842v/qdQUT3E9H9L7zwQkLViY5pdU7+Ns+QLPLEJR2+2wWEJ4+N6TUdafag8q1WV4NyeSfCrO66OY6MA5jUkbY16M0K4xDU4tjPHWRI2aZrjyYTpziemzuJvWJLajJ1gSbMsDpeFULo6CiTTvU6sm0XujmZ2s7dFWHA/7mVlpBR8wKYVz719TDjBquQHa5Vf0uPj0FAge7EvayUrJ2+vQ7wek3eJEO99GV7v1eUlWLptEZsmt3seSZRMY0jYa2NxwesbF9/2GycesgUrO5q0oa/NkXTtCaHq/4yfu9zUFXC+Nx75x76c+iizE6st1+EtEUV6nSXk60mxnbRxMbkLCmi+KZmixAi4x22Kf7AQZFT7VghYNIUfRHANgC3O//dvz4hxPFBBRPR94joVz5/2+OouBDiZiFEvxCiv6kppgSCMWJq+DWSiZttNnDT6kKURtugaIBsJ007+vw1Dvl8b0jzWcV0Dz0mY9nWh+yEUdUR3b78aKvdaoJQP0pIb2ttKlslLRRZ1jVMLqcoE/wl08Zh397BQId+9X38Z41ZU0t9coKpSpTcTFE1JNblW7Rv27xWKiahKWp4WHcVX3Z+z3IdNv3J3jds6HOkgHIRtX3quQYs0xvYIUKbIgU1xcaaCrx7aw/KSku0gmoc402UMpJaWHPbkD5Snrm2tY6mcfPsZmt/ZrVduFpek0+MWp6aQFqHW/sMDbb2SzSiTuC9/lX6/bKNBBkG3YKALWpdtddluCS53Y14TZEQ4hUhxD4hxLFCiN9Lfy/ZFCyEWCeEmO3z9w3DYc8BaJO+tzrbig7TS6aLS29iiRSLP4rNvcr1h832Hmd54HsPm+MrXBTDakJYk4YgtH2MpWCRbSI833N7PnsrYZrIp49R6q17rtaBG6z2Ct7v7FXT0qZvSfbNmQOJ/9lM/ghxvwu9Bm2yTIshMEnc98ztAzJC9mOofztn9fSM33SstAwgcbqFj2SQf54O+VLKAhcshk6om7uYhIUMTZHhTCcsmYzyshKsm6k3nfR7DkNlD5VeOaoUnz91ER59TyqG0YBjtqsenxk6WV96kyPEBiVndV8tNd+Z6dplTWQcpkuespWLNN3DsIQdT9x7olu4C7ryBscc7Ly1nb7RAP3rmH2vcGhITXpclis64SRogWLFjKa0n3UYzbCLez8Py4EFgSoIh62v3IelAqIoO1iUYXOeIM1vsRFfLxAPtwPYSUQVRDQFQCeA+/Jcp6xR22KU6GamAUH3m2qGIVOrrAbZDjelJZS2fy9EQUiXoyH1m2UZEc4V5fjM8iIe6CljqJBtWUTdCj6P+fd00yCguzllu68LA64rT25fl23qxudPW2Q8Z59lEAITtsEfTIR9LY5bFBAy27KcWZMk0zXLg1TNS6+Ty8t9ZjoWTWnAOaun+/o2Xr21B2eunBbK9FDnN6g6rOsmrvI93yXlaDKhZmtfN3MCNs9ORU3bECJ6mm4i9oNLVukPsuib3P67u7kOT7x3MyZqMtcDZgFMLrvUCf/rBh1wwzlfqfjoqJekhpde5KNtsjGLvHRjFz7r+Ey5YbRNyWHLSyUBKubxRgivtr7VYJbsEkcf7SeofOS4BTh/bWc6UqdKUPhw93mVEHkDX9RUeN6hKk2uMK+wEibIhvdadi5ss9KCnuy8o5nRbb3n9mtnwFDAFhX5aL/Fkc+eMoA9jgm1fsFPj6tlPbKvzbBXPOieuW0blKM4CghMqFXMci3KOyiEce7508vX4K6LVtpVqEjIi1BERIcT0bMAlgD4FhF9BwCEEI8CuBXArwF8G8BuIcQBfUmFS9zmKlMbw9tQN9SU58yRRn1x4kgUly3ber2TsjhDES8xZNEmAuZY2PHbamXCIBcZxUwmrjuUNgcB4cYjenHLGYsjJ4GzNQMMmshbncu5A1HyMJnKM2FKTByV8coAqA/H6v3hXZtSq/1qdDiVkhLCJRu7Mvx/hEgFZ7l8c3ek6F4qW3sn4atnL9XWd9eyjshlP//qm57vZaUlaaE42Exm6HfdfFXVzNqa+bqXWGlIdhsGm25PXahTL0n9XdYQ2JvzEnavnp4OiX/BuhnYt3fQKNDZ+s5GQSC85iIOTYevAFw/Gheun6G9l7bXTgT0S0F7lk5vxLqZKQFCCG8UU78cfdmyd0cvnrpxMGO7OrYdsaAV+/YOeoPt+FykbiFN17d87tShhbN3DJgFlyiax8njqrFv7yAOMeS6i4vFhjmGmufszvOX42d7vKkD1D5Mt/jg1+Lu2bMWm2c3Y9PsZmm/zD0n1Y+OZSGxkMiLUCSE+JoQolUIUSGEmCCE2Cj9doMQYpoQoksIcWc+6hcHcnuMY3KwTloZMUWOI832IDwDtvNFjWSTcUyB2Jh6TBWl7WcopjbtIRK+BaFqJdRkctk4N99w+OzgnTRk/UzIrowwAubo8lJjBw/4a0/dVU31N3eQd7lu+ywAwJkr7bON64WE1P9sBFTbpID2GsnwdbAJ0xq1bBNRQ93qILITGm0XYYImQq4Zky7xZpQy0xhvtiyMx92xRrBMCLif05tSi3Tz2ob6uZyug8VwLpGSimLF1WSaHPnDvHOuyaQcIMTlQ8fMQ3dzbYb21PQOyhPlCZJ21lsn+wqGXvwMLNrfD8Y219i8ELl05Kq7ptmpcyY/sfncqQP434vNGpal0xtx8tIOHOGEm5ete9xFr4VOqo2ZE+syNMmyEHTwoN8irP7ZNY+pxEeP70NVeVmk93rLnOh5yvJNPOmFGV+qy0vx97cOYNm07FcVTDb3QvMZSFZjEzZHSa5Rq2DSJJjqW1Veitff8iosBQTmtIzB1x5MubzJqnqCZbACTX0nGcxkkiYuDacrBB3lkz/GD7/7v3dHL+a0/D5DK6fueeKSDm2kxrAMCUX513Q++O71KCmhSO/S8unR+hz3TFH9N44IyBcTN36rl351t13hv2RjF8aMHhXKZyBKU9E9U8+E1qLcb1+wHA/94WWjyZK5+fg7+Ac59i+aOg7/d+kqtDdU4d6nrNyMjWye3Yyn//J34z5ylfYfFBhfW4E//+1N/QEBCAhvq4gQ5U/lpiPn4MIvP4zRhpwuYbRN7Q0prZoaKREAtsyZiC1zJgIAzlkzHZd95RHfxZDV3ePx3m/9BofOm4T799k8q1R025dffzuz7kkO674LcqkNg70TcfvDf0zs1GMjpgiIyvJOOx/Kaw+dlf78lTOX4IeP/9njk+en0Z8xoQZPPP8azl0zHXc/kYrMbJL/3b7ooav9su/I+1lVGQDSfobFSKH5FA0rXNVw1I5ENzELM2E7eDB4n+UhVd/EB78AACAASURBVMF+12ObPyVpTPfa+Jvz/+SlHZ4VNAD4v0tX464LvQk7hQDG1/m/+NkGqMnGoThbYZTgNftxm5pqThZ0lraGKuzbOxioITLRUF2Oc9d2JiJg/+ypF323u0KhSH9P/T/J0k8ldWy456fbe2x1ua9pgs3tsI1qmVm4/+adAaYoLlH8JU3kOqVATUUZLlw/I5R2XxUg3rliKhprMicrVuZzfg7RBrqb67BzoN34jtgUp97neW3B2rnJ46oDc6HY8tHj+/DtC8xJkeX3iuCN4hqFJNY9ykr07eZKx5dlgmbc8MNWc310fxv27R1ElU80uGlNNdi3dzBDizJFyhNI8LY720ltUktHOp+hONHVPf/Luf50NFbj5GVTPNv8rsFtgybBHABOcBYSXU1jfVW5b+7A/C8P5hYWihIi6oq7KULYFE2yU5OQZBO3XxUCoqBqsgphpV3FNMGSH5drdz3XGUSaaivQqXGA9S+Loq0ehz8kEfwmWOomw9gfULZme7TiIqP6k6Tr4VTEfW+ICL973xZcvbVHW5bJwTyJSf3dl67GF083B52wrYe8deMsyURXab+Vlnk9wlztxSHCsGvPF/L2xtUt1VSk7kdFWWnG6vyeLTNx/1WZq66miKRuMts13UOLS1GrqmaoN90j3f3QyYSZjvHI2ctr8tFS+cBRcwMTCQPee1NVEdzGg6MSugVnbjpt+RT87n1bQiWtdtcY4oq8N1ryU2uWtE+HzW/xmuFr+2nvD7bmsqbaL5ueWjg7ffmQuXsupg8FOEVJE7efjhDCx3+0C79735bYTZ6LHb4bSWHpm6HS32FhPx+iPFuBx3/FIXUBqibJXYko4D7FF9vnYZM/KIqTbmZ94plNVI6yfY2Dn5i103TBiHDxktYUSbeqNMCELcxjdP2fPMfbHw4gpYVbGtIkV1dH1w79/qvW4d+OXZDTNu0KEzaT1yCCwtXGrWy8aH0XLt3YhcPnt6T7w7FV0ScyDdXluO+KtdizZabxCUxr8l8Yk1EXLIyJV50+XlXw+d3Dh65ej2+fb9bmJMnUJm+wIVNbO7KvFTef2G8sT01ouWtpahXe1B510eEyC8/cREShNanuNbrBPJZNH4fB3omhypA5ut9f46uGVbbtB1ZamoENlZuJq5XqaKxOmwm6+eSSNNfTCZoFYPlv3U789gqK5Dq0X/j2OBJgn6IYiftlUttx2t7fNLcVqTwhtz3wLIQY0naYUKtdOaoU563tTDvLqQEXvnT6Itz+8B+Nk4B8rcJka0Ziq+EaV10e2VRPx+ELWvGDx19AV3NwnpWeiXX40ytvAADevbUHV37tV+kV4ovXz8Dq7nDmjGNGj8Irb7ydOTmyFH2nNlbjqQCfAKBwVud0z9m9/Gzy5tUqUX5+evmadHs4cUkHrv7Go966RD9VZIhSz8JdhFG1XRm+iQnVAfBGGFMJ0nSHfc3iuo7R5aXY7eRhqnY0DLsU0xaZPUoCXr9JpxqW3K+NXrqxG2d+/hfGutnnGAIu29iFUiIcrviC+d2nMBqOuLAxeY6rfHfFfJQxvHluJ5Fru8fj5rufwtJpKW3KF05bnFV5o0pL8JPL1/hGVzRpMnXbI5vpSrx7aw/qRo/CplnNKC8rwTd2L8sIVBRp3Ij4rArBHzru6MUZ/nNhji2UQTtHsKYoB8TWpixbddgwtX7Vu2j9DHQ7k3N1NaFzQi0u3tBVEJ0HYL+qla3ABAxN4LbPazE4LtqVpe526NxJ2Ld30CrJ6h3nL8eDV29wykmVNNeJBHXu2k6r6Hc/umw1vr57GQBvCG3/unq3q2NhmGhdvuUXRlNK+ylsDbEa++/Hzvd8l00tqSQVttQ3x4zmmk35nKKinuoaxxxQ3Z5+DhH7rCiP0dQ/ugFMBnsn4pMn6Vf+w5gXffS4BQBSOVXioKKsFPv2DnrCHauccsgUbJ83JHi0GXLiuJPzcT5mmfPbU4tcan4pmQyhSLtnStC5/rDZ6WhpMyaktDE2ZteZ583d5IkiWmIAwH+8I/X8d6/xJheOtfYx9GebZjVj0dRx2Ld30DqBsw0t9aMzLEjyOZaPq6nAddtnp9v93Lb6WDQY92r8RtMU8Fx/TXc4DVwuCNNGCvjWBsKaooTQRSBTV5HNZdjhGYsi9CUFMh+NRJgEpabrdF94gaFV8z6fUMDyCpv7fNVM84UywQ+iraEqHUpc14lp5znKRbo20EcHRJuztVXPloEpDbjvabuoWEcsaMFXH0hFEawqL8NDV6/PSG5sYpEhmERdiHJc3nfEnNDHhGWKY4rU7ZPgMFfYPHM39L07kVVxJ1LyymrQgLxpdjOu3daDozSmRElA8Aq7bq4eP1rHVuGmHXOwpltvxlUZ4EQts3F2Mz7zs99b1jP8e5ikKa2u7Gzkr8HeiRjsHXTK9ztnYZCvcUQI/QQ4apXKS10zzdxd1B9eet34eyFP3E9bPjV4pwBUk+LIAb+yrklxwUJRQrjmKZk/xFG6UL5potT5bLv/qnUZmZJTdY236b/497diLU9HmAUlG3M3IVLCwl0XrkCHb2ALV3gaul9qR19iGWghqJNaPLUB94QId2v7CN93uM+k2z3W0mxCPZm7sievhochTEQmG05fPtUoFDXVVuB3L6TM/VRTkmzMhK7dpg/IYItJCxAZ5QGunNGEO89fbp3w1rZ/CDPwLnSSC4dZ2HBxfTt2r56Ot/YfxPGLJ+PW+5/BE8+/5rv/sQPt+NFv/4Lu5loQUUYUpxMWTw5dhzCEXYk/ZmG78XfT02hU/EPaxobPzxZlOCiyNEUA/J9LLGVnUcihcyfh9of/GKt2KCxxiy43HtGL6T9+GstCpgrIph5BeRYL2Sys2ScEuy2+PkVZ1CVdboh9C/jWBsLmcwWMzqdIpWeifaLQxpqKDNv1IFV1lJXAoA4pW9xkbkEvn5vluam2ItTEpHNCrdkkTABDAlIy2PiDAfGsKKZlogyfIn/UVfZs6xDm2cRxvSukaIlxdOBzW1Pv4Lz2sVm3hzD34mPH9wEApgY44J/sE1J85sS6jHPpzpxEG5/SmMoOv8KQg82P285aglvOSPlWVFeU4aqtPagcVWpM8rplzkTs2zvoG3hm395BXH9Y9ITJhcZ7Ds0M5mGLbQhov2OSQLdYojtl2PQSNmVmU9j3L14ZmKRTxZ0Q50tTlI1poo6m2gpcvrm7oBz7C3neHsXCwMXv3TVp/4JYMnUcNvRMsO5XrIORFCgsFCUEwb9jCWqWUSZoUTsat5GXEMW+KuWXLyFO5NC1pnfdvTe2fhpBvgk2zqhBv6X3CWgNca+2mMpzncV15g3qVl3I0KA6F86QGDPpqHXJDbUDHQ0Z2zbNbsZj12/CdwJyvDSETE7ovgezW1Lmdbk0ewmib3KDb7JF16TMz4k838RdI1N5utQNVuWmo53Zt2N38Sab8+rw86sCgO6JtRl5WB67fhP+6+SFoco/PmEN4bSmmoyoeYWOydSqUPyIVR67flNG8tFijJD6waPnonN8PO1FflTZhHSvHFWKm0/s11jO+J83rhDy+YDN5xJC15nH0akERZ+zPYUcOeao/lb86/d/m13F8kDQtY6vrcSezd3pzN/ackKeVwCY6wiS7xjQm7pkYxammjnqWOL4tBw+3850ze+effmMJfjeb55PxMlfJlddZZBwklTG7VSo9pDHKHX1O/6nl6/xzV4OhPMvCSLtW+dU6eYT+vG1B59Dh19+mgLjko1dqKkow2GW7wGTSZTR6fhF7Vg2bVxOJ//V5WU45ZApOP+Wh9LborwHNiHO80Wup/SyEBFGoBhVSnj7QNI9u7n8ylGloZ+/OkQ8dv2mnJn96zhiQSuOWGD2y7VFvr5xIRfFRjIsFMWI3JHIq1ieTNwheroOxRlXL1Bl3yHFlYclm2Pixu0U3rlyWuC+Y5wJ57hq82Q5HZxLpMwc9u0dzNjnjbcOpD/Xjx7qjI7sC9fZ2T7VDscMybpcn4I7Gqtjce7Mhrlt9Xj4mZdjKStIs+FqMrfMaY7V3loI++emm3hU+wimkywiEsaBetsm1Y9Oh562Oj6Pq7M1FWW4ZGNX3s5vIq7+MBtFZOvYZNoQEeVFG1JhmVDYhNxP1DnabzVnTxLMbR2Dh599xfe3s1dNwwt/exPHZaHF+uJpi3CvZaAZP8Ik2f7Ju9bgr6+/HflcUeoRB+qrVDmq1Crya6Ej37NvnXcILvryw9jQ05zbOhShls6FhaIE8WsYYZqKztnOdlwMWi3fPLsZH7/7KZx6yBTjflE6pqR9imwIU+9tvRPx9v6DOHSe2ek7bXNveApz2+rRMa4a3c21uGZbykTxtzdsRmnIGxm3JVaSA0wcZW+e3RybUFRhndA2HoauX4R+cOrebsS1fJJv44fz1nbiL6+9medaJMM8S1/BuGgeU4meiXXYs6U7cF838WsxOErH0efIiW5XdDbig0fPDbQqiIOVXeO1QlF9VTk+dMy8rMpfOr0RS0MGNTh/XScef/5vWDqtER+7+ynr48bXVWb4KRcDUcLOFxuzJo3Bdy7MfcJlNp9jMvDYc4ZoH6Zd5dVo/1/cb3ajRWNNBe6+bDUA4LmX37A6xpYNs5px452PxVqmH0LEY2ZARNhhocmxubcbZzWjclQpvi35efgFbQga1OPuWCJFlAo9wY+ebDNOmS1Mtd3cLNng+rGE0RQlzenLp+Cbj/wp1DGuRW1kt5yYHuJF62fEU1CB4Gri779qXVYmqlEEgVGlJbjj/OV25SO8T1G+iKXfl03GiLI2XZroLGQWo7P5zIl1+MElqwDo720+w4SHJtCBO7iI67ZHD1oyUpGtjjbNyq2GKg5YKEqQuDsQXXmqXXRVecqsYHIe/QDCakVs2HvEnNAO40lh6qTj8vNOal4SzRzSe5Dq3xKHujzOJmOvTQVOO2Qq3ndHdgL8v+ycj4/f/RTmt4/Fo3981bjvZZu6MNDRgC/d9wyA5HwHrhzswZWD4UKEz2sbi5OXduC05WbtMRONxix92ZKWVQrB7DmXxH29/R0N+OrZS9P+psVKobSDbMaVYJko+GUaDuZ0uUYIke6nlk3X5/ArVPJv4zRMGT2qNNIAduE6fVZ0F/VlViesHY3V+MSJ/fjAUXPDVyAmkuhUdw60Y4Oy8pDrztsqqlxMdYpjtfYbu5eFDglrw+hyrz3/SiescmuEnChJEEbDVRKDFNtSPxrXHjoLpSUUeO6zV01HvxRJrpDW5EtLCNceOivycyyUydRwJ+n7XEhtMklsoyqGSbq+oH1sYETYAgyQ6EGvKcptxd0op2HMoWudPG/z2s2Caa7NWHPFDYfNwcKOsZjRXABRD4twQGBNUUJsmzsJH7zridDHmRxWbVZNypzM0et6hrKhr5zRhKYsnEeL12kuuXqbzRzjOW8s+XOy7Ph1VVD7utOWT8Fh81sC25kpYIDtfTMNzC31o/Hcy2/YBztIoInk89wMkw0L2sfikWdfQUMWCYxzRRwTdF1qAZVvnncIHvjDX7M+X7FQKKG3372tB50TarC6a3zwzg737FmLf/vfJ3FZQNCVYwfaAy0EisCKNIO5bfX47zOX5rUO3RNTqRwmNxTGImkYWCiKEbkfKS0h/zxFITubz54ygOdf/UfGdl0kIT8Hzc+cMhDqnEVHDvvvIb8ufW9p+4iD9isku/6gSyIiK8HbJKTFMQ5PH1+T9o9b0F6PB/4QT+AGxo5sHuEXTluEZ//6emx1YcJz5eBM7BxoQ3sRhGCPo9sf76RMCMqxNHlcNSaPK9zw3XFTGCJRKqJk2Kio1RVluHxzcFARNc9VMeHmj4srfHecCJEK0z+/rR6zW8bkuzqhYaEox4TtbPyyvQuRilDjhy5iXTbMaqnDt34ZzmFbpxFIItxpLqN15XIFrRBEIhu57Ly1wSafNsRxb6/Z1oPrvvlrLJk6Dh/5wZMx1Co8trLs2KrUKnV1womOi4VlIaNljUSaaiuwZU5zYuHzR5WWoLu5LpGy4yaO/nF8bWq8PHSuOeroSMMvLcBwo8wn+FGx0Dq2KlQajlxDREUpEAEsFOUEufPOZt5n5c+SwBpPb0tqdT+M05zOZnpCTKE73ZXM3tb60Pkqeluzf1lNE1/byX3Qs1LPceG6Gbj36RetyrYpLxSk/zo/JtvssJHu/JjaVINP78qvZtT2Ki7e0IX2hipsnl18EXpUqstL8XcpPxeTDKUlhI8c1+f729d3L8Nb+w/muEb5I46RrqG6HI9cuwE1OV6YKHST9Jt29GLxjd/HV8/OrxlWEKNKC/s+jiROWTYFn/rJ0/muRtawUBQj6pzO/3XVv8SDvcnnR9Bh6loKMeb8gvax+N5FKzAtZNLAH79rdeIR7Gy76ZaAZIqqkHD+uk4A2WtlQmZLyvp8+eLYgXb8fF/u/QBshbvKUaU4YUlHspXJMYXii5AE3zz3EDxYwH4lw9VxXEdcTa2u0s6vaCShS0wuE0cqg2y474q1sSTwZeLh6IWt+NRPni7I+WIYild/WMBEXb3oDzAD2z6vBUAyJmg2zTib1a2PHrcgVUaMc6bp42tDT8Jax1ahKotVQTeXUX1V9gNpkJNvMfkUxXKOmCfUa7pTzrl+97nGiVCUbYjkYuL67bMSW3gpnJaaHLNbxgw7IZbJD8Nh7cA2SEVSjK+rxJgYxmEmHgpd+2kLa4oSwJ3LXrd9Nt7zP49iUn08JmNnrpyKXcs6UJljB8E45uYTh0m8/wvXdeLsVdNy8gySkoniKNYjwMTUF+YyTO2Kzka8/8hebEvAl6CAZFkPJyzpSHxSPzyGxdzAJofRqRs9CuVlxbumOxzek+EyCTaxcEqD8Xeiwu3vdSQezr/I7ocKC0UJsmJGE75/8SrPNlODDGpMRJRzgch7/jD7hjUejJ8kXv5cPoNC6Fty2cHF/biC/L6O6m+L+YzOefP85MLkVImLYh8I88E9V6zF2wf4xkWhtITSOYaWTiu+BJHF9tTnto7Bw8++4t04/GWiQG3Yw9dswIEieodvPGJOoEVSVIaD9hNgoSgRTI0j6XYTdUJm9ilKlnuvWIvXY1wxndpYjaf+8vfYygtLXJ3Dkqnj8JVfPIuFHfF2YlGqpwq51XLy1uIZE3JCPgWE7120QhuZMhf4tf3Ro0oxMYGomMVOLfuyhObo/lbcev+z+a5G1hTb/PFzpy3CMy95w+UX2zUkQbH5ox070J5Y2dObanDy0g6ctLQjsXPkAhaKcoxRU5S7aoSi3AldWZeQDXEcEem+ee4hgVnEiw03EW/zmPyZHuraZOeE2pzWIwr5WrnK53s8fXx+notpMebX123MYU2Y4cxNO3qx94jefFcja0qKbKyqqxyFWZNSUVtXdzXhB4+/gKsGe3JahyTyzh02bxIWTS0+TWMhUlJCuPbQWfmuRtawUBQjNloa0ypyHCGJo2I68+KpDbhqcCaO6kvG3CgO5Jj4F22YgXO++CAm5UmYKClQPXIYLeKndy305KrIxRUV20RBx0g2JfPzMxjOEemY5LntrCV49R/7AaTaktqcRvL7lg/+84R+/O0fb2NcjoPU3HLGEsy46s5YfU//Zef8+ApjhgUsFCVAWAfEQo/vTkRZJwusqUiZW3UEZA6Pg629k7C1N3/J+JYMg5WnVV2pyG1PPP+32Mv+yplL8NAzmSt+w2XqXEhRA3PFCLxkJkf0TTY7uxcjtZXFO/UqLyvJuUAEYNhZgjCFSV7eTCJ6P4BtAN4C8DsAu4QQLzu/7QFwKoADAM4TQnwnH3WMgisMja/TdxgjddF0+vhafOrkfiweBgKDjtrKMvztH/tj13jEVVqUaEFTGquxqqsJF66bEVMtgP6OBvR3JD/R4Yl67hmp/RuTP4qxzU0el1oc7EvI6X044j7mw+e35rUezPAmXzEt7wIwWwjRC+AJAHsAgIh6AOwEMAvAJgAfIaKiyc5VXlaCfzlmHm595xLtPv7mJan/+ZzE5WJcWdM9IascQQVPgU/CowThGFVagk/vGsBcn8SQq7qaIpfrR1lpMt1RMU6aio33HT4HTbUVaf9DhskVxbj44a6bjc5jNNlio6SE8PA1G3DTjjn5rgozjMnLCCaE+K4QYr/z9R4Arui/HcAtQog3hRBPA3gSwEA+6hiVw+a3YJIhJ4/fBM3dFHZy+V+7FuI/3rEg1DFM8sQ9CY97zM+mfnectxzv3ppysI1b1kgiZ1A+yKdvYJKY2s2Ovlb8/Mp1w8YvLC7OWJGd2TEzPHEXR0eiqW02jBk9KrHFM4YBCsOn6BQAX3Y+tyAlJLk862zLgIjOAHAGALS3JxdmMG78pgxRJ6mrHb+POEiqa14UkPyMKS56JtWhZ1JdImVXl5di58I2HNlX3OYRB4fpPGd8bQWef/XNok6amWuu2DITV2yZme9qDGuKURNcCNYhDMNkkphQRETfA9Ds89OVQohvOPtcCWA/gC+ELV8IcTOAmwGgv7+fuxaHjnHJBzKw5bHrN6GMV44zKC8rwVv7D1rvH9cddE01ykoKc1JLRNi7o/jD7Q5X3nvYHJz+2fsx38eUkmEYe1yhiDVFDFNYJCYUCSHWmX4nopMBbAWwVgzZmzwHQI773OpsGzb4hafd2jsJH//R07Fofioj2ihHNfl58N3rtSt1Uesy3LnjvEPws9+9mPPzXrqpG2NGj8L2eYVjpnb7OcvwxPOvJVK2G1I8ziARI5lqJ4JkMa7MM0wh4aZtYJmIYQqLfEWf2wTgMgArhRBymuTbAXyRiD4IYBKATgD35aGKOWVuWz327R3Max2ids5jq8vjrUgRM7mxCr967lWUBswap4+vtUqyGfeAWVNRhos2dMVWnptUtqYielLf3tZ69LYmo3koLyvJy3s1xQk73xUywe1tZy3BDx9/IYkqxUKNI2ROzGMyYYYZDkT1I2YYJlny5VP07wAqANzlaE7uEUKcKYR4lIhuBfBrpMzqdgshDuSpjgwTik/vGsCDf3jZk/Q0Dgp1Zf7qrT1YPLUBA+w35sFdBZ42Ppwpa9/khoLOydLbWo8PHzsfa7vj82VkmJGIG5CENUUMU1jkRSgSQkw3/HYDgBtyWB2GiYXGmgqs75kQe7mFOnCOLi/F9nm+cVCKjvU9E7D/gL2fl4nmMZUAgK4JyQSkyCeHDpMIgczwoVD7RxPuOhf7FDFMYVEI0edGFO6q/2dPGcDvX3rdvHMO4b658EhHKMpvNUYEHz+xP7ay+iaPxdd3L8OcljGxlckwzPDB9S3mvp1hCgsWinLEjgWtuO2BZ7HGMT1ZMaMpzzXywrbNhUen43e0bNq4PNeECcs8jtDGMDmhUM2LTQxFn8tvPRiG8cJCUY6Y2pTyL6iJ2d8kLlhTVHj0TKrD/VetwzgOZpFBY00Fzl/Xme9qMAzDhKakQBIVffuC5fjDi4VjscIw+aYwZ+hMzmGZqDBprKnIdxUKkvuvMkb8ZxiGKViGfIryWg10N9ehu3n4+T4yTFQKM4sjk3PaG6ryXQWGYRiGGfZMrE8FY9k8xy+/PcMw+YI1RTkianLUXFFaUoSG2QzDMAxTZIyvrcQvr91QsOb0DDNS4TcyxxSjUyjDMAzDMPFRWxk96TXDMMnA5nMMwzAMwzAMw4xoWChiGIZhGIZhGGZEw0IRwzAMwzAMwzAjGhaKGIZhGIYpKtzcf4fNa8lzTRiGGS5woAWGYZgIfOCoubj7iRfyXQ2GGZFMHDMaT9+4BcTRi5iY2dAzAd/99fP5rgaTB1goyhFb5kzEB777BLZbrmrNmhQuodpJSybj4WdfiVI1hmEicGRfK47sa813NRhmxMICEZME//6OBfj7m/vzXQ0mD7BQlCOmNtVg395Bq33/9+KVaKqtCFX+e7bPjlIthmEYhmEYxqG8rATlZeX5rgaTB1goKkCmNtXkuwoMwzAMwzAMM2LgQAsMwzAMwzAMw4xoWFPEpLlmWw8WTRmX72owDMMwDMMwTE5hoYhJs2vZlHxXgWEYhmEYhmFyDpvPMQzDMAzDMAwzomGhiGEYhmEYhmGYEQ0LRQzDMAzDMAzDjGhYKGIYhmEYhmEYZkTDQhHDMAzDMAzDMCMaFooYhmEYhmEYhhnRsFDEMAzDMAzDMMyIhoUihmEYhmEYhmFGNCSEyHcdsoaIXgDw+3zXw6ERwF/yXQmG0cDtkylUuG0yhQy3T6ZQ4bYZjslCiCa/H4aFUFRIENH9Qoj+fNeDYfzg9skUKtw2mUKG2ydTqHDbjA82n2MYhmEYhmEYZkTDQhHDMAzDMAzDMCMaFori5+Z8V4BhDHD7ZAoVbptMIcPtkylUuG3GBPsUMQzDMAzDMAwzomFNEcMwDMMwDMMwIxoWihiGYRiGYRiGGdGwUGQBEX2KiP5MRL+Sts0jonuI6CEiup+IBpztREQfJqIniegRIlogHXMSEf3W+TspH9fCDC9Cts1VRPSKs/0hIrpaOmYTET3utNvL83EtzPBD0z7nEtHPiOiXRPQ/RFQn/bbHaYOPE9FGaTu3TyZWwrRNIuogojekvvNj0jF9zv5POmM/5eN6mOEFEbUR0Q+I6NdE9CgRne9sbyCiu5x55F1ENNbZznPPOBBC8F/AH4AVABYA+JW07bsANjuftwD4ofT5TgAEYDGAe53tDQCecv6PdT6Pzfe18V9x/4Vsm6sAfNOnjFIAvwMwFUA5gIcB9OT72viv+P807fPnAFY6n08BcL3zucdpexUApjhtspTbJ/8l8ReybXbI+ynl3OeM9eSM/ZvzfW38V/x/ACYCWOB8rgXwhNNH/hOAy53tlwO4yfnMc88Y/lhTZIEQ4m4AL6mbAbgrnGMA/NH5vB3AZ0WKewDUE9FEABsB3CWEeEkI8VcAdwHYlHztmeFMyLapYwDAk0KIp4QQbwG4Bal2zDBZoWmfMwDc7Xy+C8AO5/N2ALcIId4UQjwN4Emk2ia3TyZ2Fnm9CQAABSRJREFUQrZNX5yxvU4IcY9IzUA/C+CwuOvKjDyEEH8SQjzgfP4bgN8AaEGq7/uMs9tnMNTeeO4ZAywURecCAO8nomcAfADAHmd7C4BnpP2edbbptjNM3OjaJgAsIaKHiehOIprlbOO2yeSSRzEk1BwFoM35zH0nk290bRMAphDRg0T0f0S03NnWglR7dOG2ycQOEXUAmA/gXgAThBB/cn76fwAmOJ+5/4wBFoqicxaAC4UQbQAuBPDJPNeHYVx0bfMBAJOFEHMB/BuAr+epfszI5hQAZxPRL5AyC3krz/VhGBdd2/wTgHYhxHwAFwH4ouwLxzBJQUQ1AG4DcIEQ4lX5N0c7yXl1YoSFouicBOCrzuf/RsrEAwCeg3d1qdXZptvOMHHj2zaFEK8KIV5zPt8BYBQRNYLbJpNDhBCPCSE2CCH6AHwJKX8hgPtOJs/o2qZj0vmi8/kXzvYZSLXDVqkIbptMbBDRKKQEoi8IIdwx/XnHLM413/yzs537zxhgoSg6fwSw0vm8BsBvnc+3AzjRiQSyGMArjqrzOwA2ENFYJ1rIBmcbw8SNb9skomY3MpITka4EwItIORd3EtEUIioHsBOpdswwsUNE453/JQCuAuBG8rodwE4iqiCiKQA6kXJi5/bJ5ARd2ySiJiIqdT5PRaptPuWM7a8S0WKnbz0RwDfyUnlmWOG0p08C+I0Q4oPST7cjtfAJ5/83pO0898ySsnxXoBggoi8hFbmrkYieBXANgNMB/CsRlQH4B4AznN3vQCoKyJMAXgewCwCEEC8R0fVIDfAAcJ0QQnXyZJhQhGybRwI4i4j2A3gDwE5H/b6fiM5BqqMsBfApIcSjub0SZjiiaZ81RLTb2eWrAP4LAIQQjxLRrQB+DWA/gN1CiANOOdw+mVgJ0zaRilR3HRG9DeAggDOl8ftsAJ8GMBqp6F935uQCmOHOMgAnAPglET3kbLsCwF4AtxLRqQB+D+Bo5zeee8YApeZEDMMwDMMwDMMwIxM2n2MYhmEYhmEYZkTDQhHDMAzDMAzDMCMaFooYhmEYhmEYhhnRsFDEMAzDMAzDMMyIhoUihmEYhmEYhmFGNCwUMQzDMAzDMAwzomGhiGEYhhnRuIk5GYZhmJELC0UMwzBM0UBE1xHRBdL3G4jofCK6lIh+TkSPENF7pN+/TkS/IKJHiegMaftrRPTPRPQwgCU5vgyGYRimwGChiGEYhikmPgXgRAAgohIAOwH8PwCdAAYAzAPQR0QrnP1PEUL0AegHcB4RjXO2VwO4VwgxVwjx41xeAMMwDFN4lOW7AgzDMAxjixBiHxG9SETzAUwA8CCAhQA2OJ8BoAYpIelupAShw53tbc72FwEcAHBbLuvOMAzDFC4sFDEMwzDFxicAnAygGSnN0VoANwoh/lPeiYhWAVgHYIkQ4nUi+iGASufnfwghDuSqwgzDMExhw+ZzDMMwTLHxNQCbkNIQfcf5O4WIagCAiFqIaDyAMQD+6ghE3QAW56vCDMMwTGHDmiKGYRimqBBCvEVEPwDwsqPt+S4RzQTwMyICgNcAHA/g2wDOJKLfAHgcwD35qjPDMAxT2JAQIt91YBiGYRhrnAALDwA4Sgjx23zXh2EYhil+2HyOYRiGKRqIqAfAkwC+zwIRwzAMExesKWIYhmEYhmEYZkTDmiKGYRiGYRiGYUY0LBQxDMMwDMMwDDOiYaGIYRiGYRiGYZgRDQtFDMMwDMMwDMOMaFgoYhiGYRiGYRhmRPP/AYE/MjjPYJGBAAAAAElFTkSuQmCC\n",
  842. "text/plain": [
  843. "<Figure size 1008x288 with 1 Axes>"
  844. ]
  845. },
  846. "metadata": {
  847. "needs_background": "light"
  848. },
  849. "output_type": "display_data"
  850. }
  851. ],
  852. "source": [
  853. "%matplotlib inline\n",
  854. "import matplotlib.pyplot as plt\n",
  855. "\n",
  856. "fig, ax = plt.subplots(figsize=(14,4))\n",
  857. "ax.plot(data[:,0]+data[:,1]/12.0+data[:,2]/365, data[:,5])\n",
  858. "ax.axis('tight')\n",
  859. "ax.set_title('tempeatures in Stockholm')\n",
  860. "ax.set_xlabel('year')\n",
  861. "ax.set_ylabel('temperature (C)');"
  862. ]
  863. },
  864. {
  865. "cell_type": "markdown",
  866. "metadata": {},
  867. "source": [
  868. "使用`numpy.savetxt`我们可以将一个Numpy数组以CSV格式存入:"
  869. ]
  870. },
  871. {
  872. "cell_type": "code",
  873. "execution_count": 32,
  874. "metadata": {},
  875. "outputs": [
  876. {
  877. "data": {
  878. "text/plain": [
  879. "array([[0.73171836, 0.46544202, 0.72372739],\n",
  880. " [0.32390603, 0.09679475, 0.95467059],\n",
  881. " [0.36051701, 0.78361037, 0.00716923]])"
  882. ]
  883. },
  884. "execution_count": 32,
  885. "metadata": {},
  886. "output_type": "execute_result"
  887. }
  888. ],
  889. "source": [
  890. "M = np.random.rand(3,3)\n",
  891. "\n",
  892. "M"
  893. ]
  894. },
  895. {
  896. "cell_type": "code",
  897. "execution_count": 33,
  898. "metadata": {},
  899. "outputs": [],
  900. "source": [
  901. "np.savetxt(\"random-matrix.csv\", M)"
  902. ]
  903. },
  904. {
  905. "cell_type": "code",
  906. "execution_count": 34,
  907. "metadata": {},
  908. "outputs": [
  909. {
  910. "name": "stdout",
  911. "output_type": "stream",
  912. "text": [
  913. "7.317183558113176112e-01 4.654420244898096470e-01 7.237273924754552556e-01\r\n",
  914. "3.239060308567449642e-01 9.679474636543183852e-02 9.546705930168928322e-01\r\n",
  915. "3.605170063363589694e-01 7.836103655978251536e-01 7.169228636445423852e-03\r\n"
  916. ]
  917. }
  918. ],
  919. "source": [
  920. "!cat random-matrix.csv"
  921. ]
  922. },
  923. {
  924. "cell_type": "code",
  925. "execution_count": 35,
  926. "metadata": {},
  927. "outputs": [
  928. {
  929. "name": "stdout",
  930. "output_type": "stream",
  931. "text": [
  932. "0.73172 0.46544 0.72373\r\n",
  933. "0.32391 0.09679 0.95467\r\n",
  934. "0.36052 0.78361 0.00717\r\n"
  935. ]
  936. }
  937. ],
  938. "source": [
  939. "np.savetxt(\"random-matrix.csv\", M, fmt='%.5f') # fmt 确定格式\n",
  940. "\n",
  941. "!cat random-matrix.csv"
  942. ]
  943. },
  944. {
  945. "cell_type": "markdown",
  946. "metadata": {},
  947. "source": [
  948. "### Numpy 的本地文件格式"
  949. ]
  950. },
  951. {
  952. "cell_type": "markdown",
  953. "metadata": {},
  954. "source": [
  955. "当存储和读取numpy数组时非常有用。利用函数`numpy.save`和`numpy.load`:"
  956. ]
  957. },
  958. {
  959. "cell_type": "code",
  960. "execution_count": 36,
  961. "metadata": {},
  962. "outputs": [
  963. {
  964. "name": "stdout",
  965. "output_type": "stream",
  966. "text": [
  967. "random-matrix.npy: data\r\n"
  968. ]
  969. }
  970. ],
  971. "source": [
  972. "np.save(\"random-matrix.npy\", M)\n",
  973. "\n",
  974. "!file random-matrix.npy"
  975. ]
  976. },
  977. {
  978. "cell_type": "code",
  979. "execution_count": 37,
  980. "metadata": {},
  981. "outputs": [
  982. {
  983. "data": {
  984. "text/plain": [
  985. "array([[0.73171836, 0.46544202, 0.72372739],\n",
  986. " [0.32390603, 0.09679475, 0.95467059],\n",
  987. " [0.36051701, 0.78361037, 0.00716923]])"
  988. ]
  989. },
  990. "execution_count": 37,
  991. "metadata": {},
  992. "output_type": "execute_result"
  993. }
  994. ],
  995. "source": [
  996. "np.load(\"random-matrix.npy\")"
  997. ]
  998. },
  999. {
  1000. "cell_type": "markdown",
  1001. "metadata": {},
  1002. "source": [
  1003. "## 更多Numpy数组的性质"
  1004. ]
  1005. },
  1006. {
  1007. "cell_type": "code",
  1008. "execution_count": 38,
  1009. "metadata": {},
  1010. "outputs": [
  1011. {
  1012. "name": "stdout",
  1013. "output_type": "stream",
  1014. "text": [
  1015. "float64\n",
  1016. "8\n"
  1017. ]
  1018. }
  1019. ],
  1020. "source": [
  1021. "print(M.dtype)\n",
  1022. "print(M.itemsize) # 每个元素的字节数\n"
  1023. ]
  1024. },
  1025. {
  1026. "cell_type": "code",
  1027. "execution_count": 39,
  1028. "metadata": {},
  1029. "outputs": [
  1030. {
  1031. "data": {
  1032. "text/plain": [
  1033. "72"
  1034. ]
  1035. },
  1036. "execution_count": 39,
  1037. "metadata": {},
  1038. "output_type": "execute_result"
  1039. }
  1040. ],
  1041. "source": [
  1042. "M.nbytes # 字节数"
  1043. ]
  1044. },
  1045. {
  1046. "cell_type": "code",
  1047. "execution_count": 40,
  1048. "metadata": {},
  1049. "outputs": [
  1050. {
  1051. "data": {
  1052. "text/plain": [
  1053. "2"
  1054. ]
  1055. },
  1056. "execution_count": 40,
  1057. "metadata": {},
  1058. "output_type": "execute_result"
  1059. }
  1060. ],
  1061. "source": [
  1062. "M.ndim # 维度"
  1063. ]
  1064. },
  1065. {
  1066. "cell_type": "markdown",
  1067. "metadata": {},
  1068. "source": [
  1069. "## 操作数组"
  1070. ]
  1071. },
  1072. {
  1073. "cell_type": "markdown",
  1074. "metadata": {},
  1075. "source": [
  1076. "### 索引"
  1077. ]
  1078. },
  1079. {
  1080. "cell_type": "markdown",
  1081. "metadata": {},
  1082. "source": [
  1083. "我们可以用方括号和下标索引元素:"
  1084. ]
  1085. },
  1086. {
  1087. "cell_type": "code",
  1088. "execution_count": 41,
  1089. "metadata": {},
  1090. "outputs": [
  1091. {
  1092. "data": {
  1093. "text/plain": [
  1094. "1"
  1095. ]
  1096. },
  1097. "execution_count": 41,
  1098. "metadata": {},
  1099. "output_type": "execute_result"
  1100. }
  1101. ],
  1102. "source": [
  1103. "v = np.array([1, 2, 3, 4, 5])\n",
  1104. "# v 是一个向量,仅仅只有一维,取一个索引\n",
  1105. "v[0]"
  1106. ]
  1107. },
  1108. {
  1109. "cell_type": "code",
  1110. "execution_count": 42,
  1111. "metadata": {},
  1112. "outputs": [
  1113. {
  1114. "name": "stdout",
  1115. "output_type": "stream",
  1116. "text": [
  1117. "0.09679474636543184\n",
  1118. "0.09679474636543184\n",
  1119. "[0.32390603 0.09679475 0.95467059]\n"
  1120. ]
  1121. }
  1122. ],
  1123. "source": [
  1124. "\n",
  1125. "# M 是一个矩阵或者是一个二维的数组,取两个索引 \n",
  1126. "print(M[1,1])\n",
  1127. "print(M[1][1])\n",
  1128. "print(M[1])"
  1129. ]
  1130. },
  1131. {
  1132. "cell_type": "markdown",
  1133. "metadata": {},
  1134. "source": [
  1135. "如果我们省略了一个多维数组的索引,它将会返回整行(或者,总的来说,一个 N-1 维的数组)"
  1136. ]
  1137. },
  1138. {
  1139. "cell_type": "code",
  1140. "execution_count": 43,
  1141. "metadata": {},
  1142. "outputs": [
  1143. {
  1144. "data": {
  1145. "text/plain": [
  1146. "array([[0.73171836, 0.46544202, 0.72372739],\n",
  1147. " [0.32390603, 0.09679475, 0.95467059],\n",
  1148. " [0.36051701, 0.78361037, 0.00716923]])"
  1149. ]
  1150. },
  1151. "execution_count": 43,
  1152. "metadata": {},
  1153. "output_type": "execute_result"
  1154. }
  1155. ],
  1156. "source": [
  1157. "M"
  1158. ]
  1159. },
  1160. {
  1161. "cell_type": "code",
  1162. "execution_count": 44,
  1163. "metadata": {},
  1164. "outputs": [
  1165. {
  1166. "data": {
  1167. "text/plain": [
  1168. "array([0.32390603, 0.09679475, 0.95467059])"
  1169. ]
  1170. },
  1171. "execution_count": 44,
  1172. "metadata": {},
  1173. "output_type": "execute_result"
  1174. }
  1175. ],
  1176. "source": [
  1177. "M[1]"
  1178. ]
  1179. },
  1180. {
  1181. "cell_type": "markdown",
  1182. "metadata": {},
  1183. "source": [
  1184. "相同的事情可以利用`:`而不是索引来实现:"
  1185. ]
  1186. },
  1187. {
  1188. "cell_type": "code",
  1189. "execution_count": 45,
  1190. "metadata": {},
  1191. "outputs": [
  1192. {
  1193. "data": {
  1194. "text/plain": [
  1195. "array([0.32390603, 0.09679475, 0.95467059])"
  1196. ]
  1197. },
  1198. "execution_count": 45,
  1199. "metadata": {},
  1200. "output_type": "execute_result"
  1201. }
  1202. ],
  1203. "source": [
  1204. "M[1,:] # 行 1"
  1205. ]
  1206. },
  1207. {
  1208. "cell_type": "code",
  1209. "execution_count": 46,
  1210. "metadata": {},
  1211. "outputs": [
  1212. {
  1213. "data": {
  1214. "text/plain": [
  1215. "array([0.46544202, 0.09679475, 0.78361037])"
  1216. ]
  1217. },
  1218. "execution_count": 46,
  1219. "metadata": {},
  1220. "output_type": "execute_result"
  1221. }
  1222. ],
  1223. "source": [
  1224. "M[:,1] # 列 1"
  1225. ]
  1226. },
  1227. {
  1228. "cell_type": "markdown",
  1229. "metadata": {},
  1230. "source": [
  1231. "我们可以用索引赋新的值给数组中的元素:"
  1232. ]
  1233. },
  1234. {
  1235. "cell_type": "code",
  1236. "execution_count": 47,
  1237. "metadata": {},
  1238. "outputs": [],
  1239. "source": [
  1240. "M[0,0] = 1"
  1241. ]
  1242. },
  1243. {
  1244. "cell_type": "code",
  1245. "execution_count": 48,
  1246. "metadata": {},
  1247. "outputs": [
  1248. {
  1249. "data": {
  1250. "text/plain": [
  1251. "array([[1. , 0.46544202, 0.72372739],\n",
  1252. " [0.32390603, 0.09679475, 0.95467059],\n",
  1253. " [0.36051701, 0.78361037, 0.00716923]])"
  1254. ]
  1255. },
  1256. "execution_count": 48,
  1257. "metadata": {},
  1258. "output_type": "execute_result"
  1259. }
  1260. ],
  1261. "source": [
  1262. "M"
  1263. ]
  1264. },
  1265. {
  1266. "cell_type": "code",
  1267. "execution_count": 49,
  1268. "metadata": {},
  1269. "outputs": [],
  1270. "source": [
  1271. "# 对行和列也同样有用\n",
  1272. "M[1,:] = 0\n",
  1273. "M[:,2] = -1"
  1274. ]
  1275. },
  1276. {
  1277. "cell_type": "code",
  1278. "execution_count": 50,
  1279. "metadata": {},
  1280. "outputs": [
  1281. {
  1282. "data": {
  1283. "text/plain": [
  1284. "array([[ 1. , 0.46544202, -1. ],\n",
  1285. " [ 0. , 0. , -1. ],\n",
  1286. " [ 0.36051701, 0.78361037, -1. ]])"
  1287. ]
  1288. },
  1289. "execution_count": 50,
  1290. "metadata": {},
  1291. "output_type": "execute_result"
  1292. }
  1293. ],
  1294. "source": [
  1295. "M"
  1296. ]
  1297. },
  1298. {
  1299. "cell_type": "markdown",
  1300. "metadata": {},
  1301. "source": [
  1302. "### 切片索引"
  1303. ]
  1304. },
  1305. {
  1306. "cell_type": "markdown",
  1307. "metadata": {},
  1308. "source": [
  1309. "切片索引是语法`M[lower:upper:step]`的技术名称,用于提取数组的一部分:"
  1310. ]
  1311. },
  1312. {
  1313. "cell_type": "code",
  1314. "execution_count": 51,
  1315. "metadata": {},
  1316. "outputs": [
  1317. {
  1318. "data": {
  1319. "text/plain": [
  1320. "array([1, 2, 3, 4, 5])"
  1321. ]
  1322. },
  1323. "execution_count": 51,
  1324. "metadata": {},
  1325. "output_type": "execute_result"
  1326. }
  1327. ],
  1328. "source": [
  1329. "A = np.array([1,2,3,4,5])\n",
  1330. "A"
  1331. ]
  1332. },
  1333. {
  1334. "cell_type": "code",
  1335. "execution_count": 52,
  1336. "metadata": {},
  1337. "outputs": [
  1338. {
  1339. "data": {
  1340. "text/plain": [
  1341. "array([2, 3])"
  1342. ]
  1343. },
  1344. "execution_count": 52,
  1345. "metadata": {},
  1346. "output_type": "execute_result"
  1347. }
  1348. ],
  1349. "source": [
  1350. "A[1:3]"
  1351. ]
  1352. },
  1353. {
  1354. "cell_type": "markdown",
  1355. "metadata": {},
  1356. "source": [
  1357. "切片索引是*可变的*: 如果它们被分配了一个新值,那么从其中提取切片的原始数组将被修改:\n"
  1358. ]
  1359. },
  1360. {
  1361. "cell_type": "code",
  1362. "execution_count": 53,
  1363. "metadata": {},
  1364. "outputs": [
  1365. {
  1366. "data": {
  1367. "text/plain": [
  1368. "array([ 1, -2, -3, 4, 5])"
  1369. ]
  1370. },
  1371. "execution_count": 53,
  1372. "metadata": {},
  1373. "output_type": "execute_result"
  1374. }
  1375. ],
  1376. "source": [
  1377. "A[1:3] = [-2,-3] # auto convert type\n",
  1378. "A[1:3] = np.array([-2, -3]) \n",
  1379. "\n",
  1380. "A"
  1381. ]
  1382. },
  1383. {
  1384. "cell_type": "markdown",
  1385. "metadata": {},
  1386. "source": [
  1387. "我们可以省略`M[lower:upper:step]`中任意的三个值\n",
  1388. "We can omit any of the three parameters in `M[lower:upper:step]`:"
  1389. ]
  1390. },
  1391. {
  1392. "cell_type": "code",
  1393. "execution_count": 54,
  1394. "metadata": {},
  1395. "outputs": [
  1396. {
  1397. "data": {
  1398. "text/plain": [
  1399. "array([ 1, -2, -3, 4, 5])"
  1400. ]
  1401. },
  1402. "execution_count": 54,
  1403. "metadata": {},
  1404. "output_type": "execute_result"
  1405. }
  1406. ],
  1407. "source": [
  1408. "A[::] # lower, upper, step 都取默认值"
  1409. ]
  1410. },
  1411. {
  1412. "cell_type": "code",
  1413. "execution_count": 55,
  1414. "metadata": {},
  1415. "outputs": [
  1416. {
  1417. "data": {
  1418. "text/plain": [
  1419. "array([ 1, -2, -3, 4, 5])"
  1420. ]
  1421. },
  1422. "execution_count": 55,
  1423. "metadata": {},
  1424. "output_type": "execute_result"
  1425. }
  1426. ],
  1427. "source": [
  1428. "A[:]"
  1429. ]
  1430. },
  1431. {
  1432. "cell_type": "code",
  1433. "execution_count": 56,
  1434. "metadata": {},
  1435. "outputs": [
  1436. {
  1437. "data": {
  1438. "text/plain": [
  1439. "array([ 1, -3, 5])"
  1440. ]
  1441. },
  1442. "execution_count": 56,
  1443. "metadata": {},
  1444. "output_type": "execute_result"
  1445. }
  1446. ],
  1447. "source": [
  1448. "A[::2] # step is 2, lower and upper 代表数组的开始和结束"
  1449. ]
  1450. },
  1451. {
  1452. "cell_type": "code",
  1453. "execution_count": 57,
  1454. "metadata": {},
  1455. "outputs": [
  1456. {
  1457. "data": {
  1458. "text/plain": [
  1459. "array([ 1, -2, -3])"
  1460. ]
  1461. },
  1462. "execution_count": 57,
  1463. "metadata": {},
  1464. "output_type": "execute_result"
  1465. }
  1466. ],
  1467. "source": [
  1468. "A[:3] # 前3个元素"
  1469. ]
  1470. },
  1471. {
  1472. "cell_type": "code",
  1473. "execution_count": 58,
  1474. "metadata": {},
  1475. "outputs": [
  1476. {
  1477. "data": {
  1478. "text/plain": [
  1479. "array([4, 5])"
  1480. ]
  1481. },
  1482. "execution_count": 58,
  1483. "metadata": {},
  1484. "output_type": "execute_result"
  1485. }
  1486. ],
  1487. "source": [
  1488. "A[3:] # 从索引3开始的元素"
  1489. ]
  1490. },
  1491. {
  1492. "cell_type": "markdown",
  1493. "metadata": {},
  1494. "source": [
  1495. "负索引计数从数组的结束(正索引从开始):"
  1496. ]
  1497. },
  1498. {
  1499. "cell_type": "code",
  1500. "execution_count": 59,
  1501. "metadata": {},
  1502. "outputs": [],
  1503. "source": [
  1504. "A = np.array([1,2,3,4,5])"
  1505. ]
  1506. },
  1507. {
  1508. "cell_type": "code",
  1509. "execution_count": 60,
  1510. "metadata": {},
  1511. "outputs": [
  1512. {
  1513. "data": {
  1514. "text/plain": [
  1515. "5"
  1516. ]
  1517. },
  1518. "execution_count": 60,
  1519. "metadata": {},
  1520. "output_type": "execute_result"
  1521. }
  1522. ],
  1523. "source": [
  1524. "A[-1] # 数组中最后一个元素"
  1525. ]
  1526. },
  1527. {
  1528. "cell_type": "code",
  1529. "execution_count": 61,
  1530. "metadata": {},
  1531. "outputs": [
  1532. {
  1533. "data": {
  1534. "text/plain": [
  1535. "array([3, 4, 5])"
  1536. ]
  1537. },
  1538. "execution_count": 61,
  1539. "metadata": {},
  1540. "output_type": "execute_result"
  1541. }
  1542. ],
  1543. "source": [
  1544. "A[-3:] # 最后三个元素"
  1545. ]
  1546. },
  1547. {
  1548. "cell_type": "markdown",
  1549. "metadata": {},
  1550. "source": [
  1551. "索引切片的工作方式与多维数组完全相同:"
  1552. ]
  1553. },
  1554. {
  1555. "cell_type": "code",
  1556. "execution_count": 62,
  1557. "metadata": {},
  1558. "outputs": [
  1559. {
  1560. "data": {
  1561. "text/plain": [
  1562. "array([[ 0, 1, 2, 3, 4],\n",
  1563. " [10, 11, 12, 13, 14],\n",
  1564. " [20, 21, 22, 23, 24],\n",
  1565. " [30, 31, 32, 33, 34],\n",
  1566. " [40, 41, 42, 43, 44]])"
  1567. ]
  1568. },
  1569. "execution_count": 62,
  1570. "metadata": {},
  1571. "output_type": "execute_result"
  1572. }
  1573. ],
  1574. "source": [
  1575. "A = np.array([[n+m*10 for n in range(5)] for m in range(5)])\n",
  1576. "\n",
  1577. "A"
  1578. ]
  1579. },
  1580. {
  1581. "cell_type": "code",
  1582. "execution_count": 63,
  1583. "metadata": {},
  1584. "outputs": [
  1585. {
  1586. "data": {
  1587. "text/plain": [
  1588. "array([[11, 12, 13],\n",
  1589. " [21, 22, 23],\n",
  1590. " [31, 32, 33]])"
  1591. ]
  1592. },
  1593. "execution_count": 63,
  1594. "metadata": {},
  1595. "output_type": "execute_result"
  1596. }
  1597. ],
  1598. "source": [
  1599. "# 原始数组中的一个块\n",
  1600. "A[1:4, 1:4]"
  1601. ]
  1602. },
  1603. {
  1604. "cell_type": "code",
  1605. "execution_count": 64,
  1606. "metadata": {},
  1607. "outputs": [
  1608. {
  1609. "data": {
  1610. "text/plain": [
  1611. "array([[ 0, 2, 4],\n",
  1612. " [20, 22, 24],\n",
  1613. " [40, 42, 44]])"
  1614. ]
  1615. },
  1616. "execution_count": 64,
  1617. "metadata": {},
  1618. "output_type": "execute_result"
  1619. }
  1620. ],
  1621. "source": [
  1622. "# 步长\n",
  1623. "A[::2, ::2]"
  1624. ]
  1625. },
  1626. {
  1627. "cell_type": "markdown",
  1628. "metadata": {},
  1629. "source": [
  1630. "### 花式索引"
  1631. ]
  1632. },
  1633. {
  1634. "cell_type": "markdown",
  1635. "metadata": {},
  1636. "source": [
  1637. "Fancy索引是一个名称时,一个数组或列表被使用在一个索引:"
  1638. ]
  1639. },
  1640. {
  1641. "cell_type": "code",
  1642. "execution_count": 65,
  1643. "metadata": {},
  1644. "outputs": [
  1645. {
  1646. "name": "stdout",
  1647. "output_type": "stream",
  1648. "text": [
  1649. "[[10 11 12 13 14]\n",
  1650. " [20 21 22 23 24]\n",
  1651. " [30 31 32 33 34]]\n",
  1652. "[[ 0 1 2 3 4]\n",
  1653. " [10 11 12 13 14]\n",
  1654. " [20 21 22 23 24]\n",
  1655. " [30 31 32 33 34]\n",
  1656. " [40 41 42 43 44]]\n"
  1657. ]
  1658. }
  1659. ],
  1660. "source": [
  1661. "row_indices = [1, 2, 3]\n",
  1662. "print(A[row_indices])\n",
  1663. "print(A)"
  1664. ]
  1665. },
  1666. {
  1667. "cell_type": "code",
  1668. "execution_count": 66,
  1669. "metadata": {},
  1670. "outputs": [
  1671. {
  1672. "data": {
  1673. "text/plain": [
  1674. "array([11, 22, 34])"
  1675. ]
  1676. },
  1677. "execution_count": 66,
  1678. "metadata": {},
  1679. "output_type": "execute_result"
  1680. }
  1681. ],
  1682. "source": [
  1683. "col_indices = [1, 2, -1] # 索引-1 代表最后一个元素\n",
  1684. "A[row_indices, col_indices]"
  1685. ]
  1686. },
  1687. {
  1688. "cell_type": "markdown",
  1689. "metadata": {},
  1690. "source": [
  1691. "我们也可以使用索引掩码:如果索引掩码是一个数据类型`bool`的Numpy数组,那么一个元素被选择(True)或不(False)取决于索引掩码在每个元素位置的值:"
  1692. ]
  1693. },
  1694. {
  1695. "cell_type": "code",
  1696. "execution_count": 67,
  1697. "metadata": {},
  1698. "outputs": [
  1699. {
  1700. "data": {
  1701. "text/plain": [
  1702. "array([0, 1, 2, 3, 4])"
  1703. ]
  1704. },
  1705. "execution_count": 67,
  1706. "metadata": {},
  1707. "output_type": "execute_result"
  1708. }
  1709. ],
  1710. "source": [
  1711. "B = array([n for n in range(5)])\n",
  1712. "B"
  1713. ]
  1714. },
  1715. {
  1716. "cell_type": "code",
  1717. "execution_count": 68,
  1718. "metadata": {},
  1719. "outputs": [
  1720. {
  1721. "data": {
  1722. "text/plain": [
  1723. "array([0, 2])"
  1724. ]
  1725. },
  1726. "execution_count": 68,
  1727. "metadata": {},
  1728. "output_type": "execute_result"
  1729. }
  1730. ],
  1731. "source": [
  1732. "row_mask = array([True, False, True, False, False])\n",
  1733. "B[row_mask]"
  1734. ]
  1735. },
  1736. {
  1737. "cell_type": "code",
  1738. "execution_count": 69,
  1739. "metadata": {},
  1740. "outputs": [
  1741. {
  1742. "data": {
  1743. "text/plain": [
  1744. "array([0, 2])"
  1745. ]
  1746. },
  1747. "execution_count": 69,
  1748. "metadata": {},
  1749. "output_type": "execute_result"
  1750. }
  1751. ],
  1752. "source": [
  1753. "# 相同的事情\n",
  1754. "row_mask = array([1,0,1,0,0], dtype=bool)\n",
  1755. "B[row_mask]"
  1756. ]
  1757. },
  1758. {
  1759. "cell_type": "markdown",
  1760. "metadata": {},
  1761. "source": [
  1762. "这个特性对于有条件地从数组中选择元素非常有用,例如使用比较运算符:"
  1763. ]
  1764. },
  1765. {
  1766. "cell_type": "code",
  1767. "execution_count": 70,
  1768. "metadata": {},
  1769. "outputs": [
  1770. {
  1771. "data": {
  1772. "text/plain": [
  1773. "array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. ,\n",
  1774. " 6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5])"
  1775. ]
  1776. },
  1777. "execution_count": 70,
  1778. "metadata": {},
  1779. "output_type": "execute_result"
  1780. }
  1781. ],
  1782. "source": [
  1783. "x = np.arange(0, 10, 0.5)\n",
  1784. "x"
  1785. ]
  1786. },
  1787. {
  1788. "cell_type": "code",
  1789. "execution_count": 71,
  1790. "metadata": {},
  1791. "outputs": [
  1792. {
  1793. "data": {
  1794. "text/plain": [
  1795. "array([False, False, False, False, False, False, False, False, False,\n",
  1796. " False, False, True, True, True, True, False, False, False,\n",
  1797. " False, False])"
  1798. ]
  1799. },
  1800. "execution_count": 71,
  1801. "metadata": {},
  1802. "output_type": "execute_result"
  1803. }
  1804. ],
  1805. "source": [
  1806. "mask = (5 < x) * (x < 7.5)\n",
  1807. "\n",
  1808. "mask"
  1809. ]
  1810. },
  1811. {
  1812. "cell_type": "code",
  1813. "execution_count": 72,
  1814. "metadata": {},
  1815. "outputs": [
  1816. {
  1817. "data": {
  1818. "text/plain": [
  1819. "array([5.5, 6. , 6.5, 7. ])"
  1820. ]
  1821. },
  1822. "execution_count": 72,
  1823. "metadata": {},
  1824. "output_type": "execute_result"
  1825. }
  1826. ],
  1827. "source": [
  1828. "x[mask]"
  1829. ]
  1830. },
  1831. {
  1832. "cell_type": "code",
  1833. "execution_count": 73,
  1834. "metadata": {},
  1835. "outputs": [
  1836. {
  1837. "data": {
  1838. "text/plain": [
  1839. "array([3.5, 4. , 4.5, 5. , 5.5])"
  1840. ]
  1841. },
  1842. "execution_count": 73,
  1843. "metadata": {},
  1844. "output_type": "execute_result"
  1845. }
  1846. ],
  1847. "source": [
  1848. "x[(3<x) * (x<6)]"
  1849. ]
  1850. },
  1851. {
  1852. "cell_type": "markdown",
  1853. "metadata": {},
  1854. "source": [
  1855. "## 用于从数组中提取数据和创建数组的函数"
  1856. ]
  1857. },
  1858. {
  1859. "cell_type": "markdown",
  1860. "metadata": {},
  1861. "source": [
  1862. "### where"
  1863. ]
  1864. },
  1865. {
  1866. "cell_type": "markdown",
  1867. "metadata": {},
  1868. "source": [
  1869. "索引掩码可以使用`where`函数转换为位置索引"
  1870. ]
  1871. },
  1872. {
  1873. "cell_type": "code",
  1874. "execution_count": 76,
  1875. "metadata": {},
  1876. "outputs": [
  1877. {
  1878. "data": {
  1879. "text/plain": [
  1880. "(array([11, 12, 13, 14]),)"
  1881. ]
  1882. },
  1883. "execution_count": 76,
  1884. "metadata": {},
  1885. "output_type": "execute_result"
  1886. }
  1887. ],
  1888. "source": [
  1889. "indices = np.where(mask)\n",
  1890. "\n",
  1891. "indices"
  1892. ]
  1893. },
  1894. {
  1895. "cell_type": "code",
  1896. "execution_count": 75,
  1897. "metadata": {},
  1898. "outputs": [
  1899. {
  1900. "data": {
  1901. "text/plain": [
  1902. "array([5.5, 6. , 6.5, 7. ])"
  1903. ]
  1904. },
  1905. "execution_count": 75,
  1906. "metadata": {},
  1907. "output_type": "execute_result"
  1908. }
  1909. ],
  1910. "source": [
  1911. "x[indices] # 这个索引等同于花式索引x[mask]"
  1912. ]
  1913. },
  1914. {
  1915. "cell_type": "markdown",
  1916. "metadata": {},
  1917. "source": [
  1918. "### diag"
  1919. ]
  1920. },
  1921. {
  1922. "cell_type": "markdown",
  1923. "metadata": {},
  1924. "source": [
  1925. "使用diag函数,我们还可以提取一个数组的对角线和亚对角线:"
  1926. ]
  1927. },
  1928. {
  1929. "cell_type": "code",
  1930. "execution_count": 74,
  1931. "metadata": {},
  1932. "outputs": [
  1933. {
  1934. "data": {
  1935. "text/plain": [
  1936. "array([ 0, 11, 22, 33, 44])"
  1937. ]
  1938. },
  1939. "execution_count": 74,
  1940. "metadata": {},
  1941. "output_type": "execute_result"
  1942. }
  1943. ],
  1944. "source": [
  1945. "diag(A)"
  1946. ]
  1947. },
  1948. {
  1949. "cell_type": "code",
  1950. "execution_count": 75,
  1951. "metadata": {},
  1952. "outputs": [
  1953. {
  1954. "data": {
  1955. "text/plain": [
  1956. "array([10, 21, 32, 43])"
  1957. ]
  1958. },
  1959. "execution_count": 75,
  1960. "metadata": {},
  1961. "output_type": "execute_result"
  1962. }
  1963. ],
  1964. "source": [
  1965. "diag(A, -1)"
  1966. ]
  1967. },
  1968. {
  1969. "cell_type": "markdown",
  1970. "metadata": {},
  1971. "source": [
  1972. "### take"
  1973. ]
  1974. },
  1975. {
  1976. "cell_type": "markdown",
  1977. "metadata": {},
  1978. "source": [
  1979. "`take` 函数和上面描述的花式索引类似"
  1980. ]
  1981. },
  1982. {
  1983. "cell_type": "code",
  1984. "execution_count": 76,
  1985. "metadata": {},
  1986. "outputs": [
  1987. {
  1988. "data": {
  1989. "text/plain": [
  1990. "array([-3, -2, -1, 0, 1, 2])"
  1991. ]
  1992. },
  1993. "execution_count": 76,
  1994. "metadata": {},
  1995. "output_type": "execute_result"
  1996. }
  1997. ],
  1998. "source": [
  1999. "v2 = arange(-3,3)\n",
  2000. "v2"
  2001. ]
  2002. },
  2003. {
  2004. "cell_type": "code",
  2005. "execution_count": 77,
  2006. "metadata": {},
  2007. "outputs": [
  2008. {
  2009. "data": {
  2010. "text/plain": [
  2011. "array([-2, 0, 2])"
  2012. ]
  2013. },
  2014. "execution_count": 77,
  2015. "metadata": {},
  2016. "output_type": "execute_result"
  2017. }
  2018. ],
  2019. "source": [
  2020. "row_indices = [1, 3, 5]\n",
  2021. "v2[row_indices] # 花式索引"
  2022. ]
  2023. },
  2024. {
  2025. "cell_type": "code",
  2026. "execution_count": 78,
  2027. "metadata": {},
  2028. "outputs": [
  2029. {
  2030. "data": {
  2031. "text/plain": [
  2032. "array([-2, 0, 2])"
  2033. ]
  2034. },
  2035. "execution_count": 78,
  2036. "metadata": {},
  2037. "output_type": "execute_result"
  2038. }
  2039. ],
  2040. "source": [
  2041. "v2.take(row_indices)"
  2042. ]
  2043. },
  2044. {
  2045. "cell_type": "markdown",
  2046. "metadata": {},
  2047. "source": [
  2048. "但是`take`也作用在列表和其他的物体上:"
  2049. ]
  2050. },
  2051. {
  2052. "cell_type": "code",
  2053. "execution_count": 79,
  2054. "metadata": {},
  2055. "outputs": [
  2056. {
  2057. "data": {
  2058. "text/plain": [
  2059. "array([-2, 0, 2])"
  2060. ]
  2061. },
  2062. "execution_count": 79,
  2063. "metadata": {},
  2064. "output_type": "execute_result"
  2065. }
  2066. ],
  2067. "source": [
  2068. "take([-3, -2, -1, 0, 1, 2], row_indices)"
  2069. ]
  2070. },
  2071. {
  2072. "cell_type": "markdown",
  2073. "metadata": {},
  2074. "source": [
  2075. "### choose"
  2076. ]
  2077. },
  2078. {
  2079. "cell_type": "markdown",
  2080. "metadata": {},
  2081. "source": [
  2082. "通过从几个数组中选择元素来构造一个数组:"
  2083. ]
  2084. },
  2085. {
  2086. "cell_type": "code",
  2087. "execution_count": 49,
  2088. "metadata": {},
  2089. "outputs": [
  2090. {
  2091. "data": {
  2092. "text/plain": [
  2093. "array([ 5, -2, 5, -2])"
  2094. ]
  2095. },
  2096. "execution_count": 49,
  2097. "metadata": {},
  2098. "output_type": "execute_result"
  2099. }
  2100. ],
  2101. "source": [
  2102. "which = [1, 0, 1, 0]\n",
  2103. "choices = [[-2,-2,-2,-2], [5,5,5,5]]\n",
  2104. "\n",
  2105. "np.choose(which, choices)"
  2106. ]
  2107. },
  2108. {
  2109. "cell_type": "markdown",
  2110. "metadata": {},
  2111. "source": [
  2112. "## 线性代数"
  2113. ]
  2114. },
  2115. {
  2116. "cell_type": "markdown",
  2117. "metadata": {},
  2118. "source": [
  2119. "向量化代码是使用Python/Numpy编写高效数值计算的关键。这意味着尽可能多的程序应该用矩阵和向量运算来表示,比如矩阵-矩阵乘法。"
  2120. ]
  2121. },
  2122. {
  2123. "cell_type": "markdown",
  2124. "metadata": {},
  2125. "source": [
  2126. "### Scalar-array 操作"
  2127. ]
  2128. },
  2129. {
  2130. "cell_type": "markdown",
  2131. "metadata": {},
  2132. "source": [
  2133. "我们可以使用常用的算术运算符来对标量数组进行乘、加、减和除运算。"
  2134. ]
  2135. },
  2136. {
  2137. "cell_type": "code",
  2138. "execution_count": 93,
  2139. "metadata": {},
  2140. "outputs": [],
  2141. "source": [
  2142. "v1 = np.arange(0, 5)"
  2143. ]
  2144. },
  2145. {
  2146. "cell_type": "code",
  2147. "execution_count": 94,
  2148. "metadata": {},
  2149. "outputs": [
  2150. {
  2151. "data": {
  2152. "text/plain": [
  2153. "array([0, 2, 4, 6, 8])"
  2154. ]
  2155. },
  2156. "execution_count": 94,
  2157. "metadata": {},
  2158. "output_type": "execute_result"
  2159. }
  2160. ],
  2161. "source": [
  2162. "v1 * 2"
  2163. ]
  2164. },
  2165. {
  2166. "cell_type": "code",
  2167. "execution_count": 95,
  2168. "metadata": {},
  2169. "outputs": [
  2170. {
  2171. "data": {
  2172. "text/plain": [
  2173. "array([2, 3, 4, 5, 6])"
  2174. ]
  2175. },
  2176. "execution_count": 95,
  2177. "metadata": {},
  2178. "output_type": "execute_result"
  2179. }
  2180. ],
  2181. "source": [
  2182. "v1 + 2"
  2183. ]
  2184. },
  2185. {
  2186. "cell_type": "code",
  2187. "execution_count": 96,
  2188. "metadata": {},
  2189. "outputs": [
  2190. {
  2191. "data": {
  2192. "text/plain": [
  2193. "(array([[ 0, 2, 4, 6, 8],\n",
  2194. " [20, 22, 24, 26, 28],\n",
  2195. " [40, 42, 44, 46, 48],\n",
  2196. " [60, 62, 64, 66, 68],\n",
  2197. " [80, 82, 84, 86, 88]]), array([[ 2, 3, 4, 5, 6],\n",
  2198. " [12, 13, 14, 15, 16],\n",
  2199. " [22, 23, 24, 25, 26],\n",
  2200. " [32, 33, 34, 35, 36],\n",
  2201. " [42, 43, 44, 45, 46]]))"
  2202. ]
  2203. },
  2204. "execution_count": 96,
  2205. "metadata": {},
  2206. "output_type": "execute_result"
  2207. }
  2208. ],
  2209. "source": [
  2210. "A * 2, A + 2"
  2211. ]
  2212. },
  2213. {
  2214. "cell_type": "markdown",
  2215. "metadata": {},
  2216. "source": [
  2217. "### 数组间的元素操作"
  2218. ]
  2219. },
  2220. {
  2221. "cell_type": "markdown",
  2222. "metadata": {},
  2223. "source": [
  2224. "当我们对数组进行加法、减法、乘法和除法时,默认的行为是**element-wise**操作:"
  2225. ]
  2226. },
  2227. {
  2228. "cell_type": "code",
  2229. "execution_count": 97,
  2230. "metadata": {},
  2231. "outputs": [
  2232. {
  2233. "data": {
  2234. "text/plain": [
  2235. "array([[0.41002411, 0.52156709, 0.77687362],\n",
  2236. " [0.86406459, 0.00587552, 0.04683701]])"
  2237. ]
  2238. },
  2239. "execution_count": 97,
  2240. "metadata": {},
  2241. "output_type": "execute_result"
  2242. }
  2243. ],
  2244. "source": [
  2245. "A = np.random.rand(2, 3)\n",
  2246. "\n",
  2247. "A * A # element-wise 乘法"
  2248. ]
  2249. },
  2250. {
  2251. "cell_type": "code",
  2252. "execution_count": 98,
  2253. "metadata": {},
  2254. "outputs": [
  2255. {
  2256. "data": {
  2257. "text/plain": [
  2258. "array([ 0, 1, 4, 9, 16])"
  2259. ]
  2260. },
  2261. "execution_count": 98,
  2262. "metadata": {},
  2263. "output_type": "execute_result"
  2264. }
  2265. ],
  2266. "source": [
  2267. "v1 * v1"
  2268. ]
  2269. },
  2270. {
  2271. "cell_type": "markdown",
  2272. "metadata": {},
  2273. "source": [
  2274. "如果我们用兼容的形状进行数组的乘法,我们会得到每一行的对位相乘结果:"
  2275. ]
  2276. },
  2277. {
  2278. "cell_type": "code",
  2279. "execution_count": 99,
  2280. "metadata": {},
  2281. "outputs": [
  2282. {
  2283. "data": {
  2284. "text/plain": [
  2285. "((2, 3), (5,))"
  2286. ]
  2287. },
  2288. "execution_count": 99,
  2289. "metadata": {},
  2290. "output_type": "execute_result"
  2291. }
  2292. ],
  2293. "source": [
  2294. "A.shape, v1.shape"
  2295. ]
  2296. },
  2297. {
  2298. "cell_type": "code",
  2299. "execution_count": 100,
  2300. "metadata": {},
  2301. "outputs": [
  2302. {
  2303. "ename": "ValueError",
  2304. "evalue": "operands could not be broadcast together with shapes (2,3) (5,) ",
  2305. "output_type": "error",
  2306. "traceback": [
  2307. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  2308. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  2309. "\u001b[0;32m<ipython-input-100-1af134c5c5d0>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mA\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mv1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
  2310. "\u001b[0;31mValueError\u001b[0m: operands could not be broadcast together with shapes (2,3) (5,) "
  2311. ]
  2312. }
  2313. ],
  2314. "source": [
  2315. "A * v1"
  2316. ]
  2317. },
  2318. {
  2319. "cell_type": "markdown",
  2320. "metadata": {},
  2321. "source": [
  2322. "### 矩阵代数"
  2323. ]
  2324. },
  2325. {
  2326. "cell_type": "markdown",
  2327. "metadata": {},
  2328. "source": [
  2329. "那么矩阵的乘法呢?有两种方法。我们可以使用点函数,它对两个参数应用矩阵-矩阵、矩阵-向量或内向量乘法"
  2330. ]
  2331. },
  2332. {
  2333. "cell_type": "code",
  2334. "execution_count": 102,
  2335. "metadata": {},
  2336. "outputs": [
  2337. {
  2338. "data": {
  2339. "text/plain": [
  2340. "array([[0.3767892 , 1.47079714, 0.31117826, 1.29726746, 0.51486767],\n",
  2341. " [0.25604237, 0.97247777, 0.34479677, 0.93969314, 0.3976715 ],\n",
  2342. " [0.81557228, 1.22841789, 0.86636095, 0.93499185, 0.28560187],\n",
  2343. " [0.52515694, 1.56792282, 1.1443364 , 1.84965072, 0.74141231],\n",
  2344. " [0.78004097, 1.51298694, 1.22023006, 1.42991218, 0.71648303]])"
  2345. ]
  2346. },
  2347. "execution_count": 102,
  2348. "metadata": {},
  2349. "output_type": "execute_result"
  2350. }
  2351. ],
  2352. "source": [
  2353. "A = np.random.rand(5, 5)\n",
  2354. "v = np.random.rand(5, 1)\n",
  2355. "\n",
  2356. "np.dot(A, A)"
  2357. ]
  2358. },
  2359. {
  2360. "cell_type": "code",
  2361. "execution_count": 107,
  2362. "metadata": {},
  2363. "outputs": [
  2364. {
  2365. "data": {
  2366. "text/plain": [
  2367. "array([3.03824466, 2.65209134, 2.94637897, 6.50153897, 5.54270391])"
  2368. ]
  2369. },
  2370. "execution_count": 107,
  2371. "metadata": {},
  2372. "output_type": "execute_result"
  2373. }
  2374. ],
  2375. "source": [
  2376. "np.dot(A, v1)"
  2377. ]
  2378. },
  2379. {
  2380. "cell_type": "code",
  2381. "execution_count": 108,
  2382. "metadata": {},
  2383. "outputs": [
  2384. {
  2385. "data": {
  2386. "text/plain": [
  2387. "30"
  2388. ]
  2389. },
  2390. "execution_count": 108,
  2391. "metadata": {},
  2392. "output_type": "execute_result"
  2393. }
  2394. ],
  2395. "source": [
  2396. "np.dot(v1, v1)"
  2397. ]
  2398. },
  2399. {
  2400. "cell_type": "markdown",
  2401. "metadata": {},
  2402. "source": [
  2403. "另外,我们可以将数组对象投到`matrix`类型上。这将改变标准算术运算符`+, -, *` 的行为,以使用矩阵代数。"
  2404. ]
  2405. },
  2406. {
  2407. "cell_type": "code",
  2408. "execution_count": 111,
  2409. "metadata": {},
  2410. "outputs": [],
  2411. "source": [
  2412. "M = np.matrix(A)\n",
  2413. "v = np.matrix(v1).T # make it a column vector"
  2414. ]
  2415. },
  2416. {
  2417. "cell_type": "code",
  2418. "execution_count": 112,
  2419. "metadata": {},
  2420. "outputs": [
  2421. {
  2422. "data": {
  2423. "text/plain": [
  2424. "matrix([[0],\n",
  2425. " [1],\n",
  2426. " [2],\n",
  2427. " [3],\n",
  2428. " [4]])"
  2429. ]
  2430. },
  2431. "execution_count": 112,
  2432. "metadata": {},
  2433. "output_type": "execute_result"
  2434. }
  2435. ],
  2436. "source": [
  2437. "v"
  2438. ]
  2439. },
  2440. {
  2441. "cell_type": "code",
  2442. "execution_count": 113,
  2443. "metadata": {},
  2444. "outputs": [
  2445. {
  2446. "data": {
  2447. "text/plain": [
  2448. "matrix([[0.3767892 , 1.47079714, 0.31117826, 1.29726746, 0.51486767],\n",
  2449. " [0.25604237, 0.97247777, 0.34479677, 0.93969314, 0.3976715 ],\n",
  2450. " [0.81557228, 1.22841789, 0.86636095, 0.93499185, 0.28560187],\n",
  2451. " [0.52515694, 1.56792282, 1.1443364 , 1.84965072, 0.74141231],\n",
  2452. " [0.78004097, 1.51298694, 1.22023006, 1.42991218, 0.71648303]])"
  2453. ]
  2454. },
  2455. "execution_count": 113,
  2456. "metadata": {},
  2457. "output_type": "execute_result"
  2458. }
  2459. ],
  2460. "source": [
  2461. "M * M"
  2462. ]
  2463. },
  2464. {
  2465. "cell_type": "code",
  2466. "execution_count": 114,
  2467. "metadata": {},
  2468. "outputs": [
  2469. {
  2470. "data": {
  2471. "text/plain": [
  2472. "matrix([[3.03824466],\n",
  2473. " [2.65209134],\n",
  2474. " [2.94637897],\n",
  2475. " [6.50153897],\n",
  2476. " [5.54270391]])"
  2477. ]
  2478. },
  2479. "execution_count": 114,
  2480. "metadata": {},
  2481. "output_type": "execute_result"
  2482. }
  2483. ],
  2484. "source": [
  2485. "M * v"
  2486. ]
  2487. },
  2488. {
  2489. "cell_type": "code",
  2490. "execution_count": 117,
  2491. "metadata": {},
  2492. "outputs": [
  2493. {
  2494. "data": {
  2495. "text/plain": [
  2496. "matrix([[30]])"
  2497. ]
  2498. },
  2499. "execution_count": 117,
  2500. "metadata": {},
  2501. "output_type": "execute_result"
  2502. }
  2503. ],
  2504. "source": [
  2505. "# 內积\n",
  2506. "v.T * v"
  2507. ]
  2508. },
  2509. {
  2510. "cell_type": "code",
  2511. "execution_count": 118,
  2512. "metadata": {},
  2513. "outputs": [
  2514. {
  2515. "data": {
  2516. "text/plain": [
  2517. "matrix([[3.03824466],\n",
  2518. " [3.65209134],\n",
  2519. " [4.94637897],\n",
  2520. " [9.50153897],\n",
  2521. " [9.54270391]])"
  2522. ]
  2523. },
  2524. "execution_count": 118,
  2525. "metadata": {},
  2526. "output_type": "execute_result"
  2527. }
  2528. ],
  2529. "source": [
  2530. "# 对于矩阵对象,适用标准的矩阵代数\n",
  2531. "v + M*v"
  2532. ]
  2533. },
  2534. {
  2535. "cell_type": "markdown",
  2536. "metadata": {},
  2537. "source": [
  2538. "如果我们尝试用不相配的矩阵形状加,减或者乘我们会得到错误:"
  2539. ]
  2540. },
  2541. {
  2542. "cell_type": "code",
  2543. "execution_count": 125,
  2544. "metadata": {},
  2545. "outputs": [],
  2546. "source": [
  2547. "v = np.matrix([1,2,3,4,5,6]).T"
  2548. ]
  2549. },
  2550. {
  2551. "cell_type": "code",
  2552. "execution_count": 123,
  2553. "metadata": {},
  2554. "outputs": [
  2555. {
  2556. "data": {
  2557. "text/plain": [
  2558. "((5, 5), (5, 1))"
  2559. ]
  2560. },
  2561. "execution_count": 123,
  2562. "metadata": {},
  2563. "output_type": "execute_result"
  2564. }
  2565. ],
  2566. "source": [
  2567. "np.shape(M), np.shape(v)"
  2568. ]
  2569. },
  2570. {
  2571. "cell_type": "code",
  2572. "execution_count": 124,
  2573. "metadata": {},
  2574. "outputs": [
  2575. {
  2576. "data": {
  2577. "text/plain": [
  2578. "matrix([[5.06458489],\n",
  2579. " [4.08471675],\n",
  2580. " [4.990684 ],\n",
  2581. " [9.17423165],\n",
  2582. " [8.08502244]])"
  2583. ]
  2584. },
  2585. "execution_count": 124,
  2586. "metadata": {},
  2587. "output_type": "execute_result"
  2588. }
  2589. ],
  2590. "source": [
  2591. "M * v"
  2592. ]
  2593. },
  2594. {
  2595. "cell_type": "markdown",
  2596. "metadata": {},
  2597. "source": [
  2598. "同样了解相关的函数:`inner`, `outer`, `cross`, `kron`, `tensordot`。例如用`help(kron)`。"
  2599. ]
  2600. },
  2601. {
  2602. "cell_type": "markdown",
  2603. "metadata": {},
  2604. "source": [
  2605. "### 数组/矩阵转换"
  2606. ]
  2607. },
  2608. {
  2609. "cell_type": "markdown",
  2610. "metadata": {},
  2611. "source": [
  2612. "同样我们也用`.T`对矩阵目标`v`进行转置。我们也可以利用`transpose`函数去实现同样的事情。\n",
  2613. "\n",
  2614. "变换矩阵对象的其他数学函数有:"
  2615. ]
  2616. },
  2617. {
  2618. "cell_type": "code",
  2619. "execution_count": 126,
  2620. "metadata": {},
  2621. "outputs": [
  2622. {
  2623. "name": "stdout",
  2624. "output_type": "stream",
  2625. "text": [
  2626. "[[0.04208911 0.65828119 0.21987187 0.10069326]\n",
  2627. " [0.61960112 0.52726045 0.35884175 0.51931613]\n",
  2628. " [0.66708619 0.76886997 0.06792093 0.6548313 ]]\n",
  2629. "[[0.04208911 0.61960112 0.66708619]\n",
  2630. " [0.65828119 0.52726045 0.76886997]\n",
  2631. " [0.21987187 0.35884175 0.06792093]\n",
  2632. " [0.10069326 0.51931613 0.6548313 ]]\n"
  2633. ]
  2634. }
  2635. ],
  2636. "source": [
  2637. "A = np.random.rand(3,4)\n",
  2638. "print(A)\n",
  2639. "print(A.T)"
  2640. ]
  2641. },
  2642. {
  2643. "cell_type": "code",
  2644. "execution_count": 127,
  2645. "metadata": {},
  2646. "outputs": [
  2647. {
  2648. "data": {
  2649. "text/plain": [
  2650. "matrix([[0.+1.j, 0.+2.j],\n",
  2651. " [0.+3.j, 0.+4.j]])"
  2652. ]
  2653. },
  2654. "execution_count": 127,
  2655. "metadata": {},
  2656. "output_type": "execute_result"
  2657. }
  2658. ],
  2659. "source": [
  2660. "C = np.matrix([[1j, 2j], [3j, 4j]])\n",
  2661. "C"
  2662. ]
  2663. },
  2664. {
  2665. "cell_type": "code",
  2666. "execution_count": 128,
  2667. "metadata": {},
  2668. "outputs": [
  2669. {
  2670. "data": {
  2671. "text/plain": [
  2672. "matrix([[0.-1.j, 0.-2.j],\n",
  2673. " [0.-3.j, 0.-4.j]])"
  2674. ]
  2675. },
  2676. "execution_count": 128,
  2677. "metadata": {},
  2678. "output_type": "execute_result"
  2679. }
  2680. ],
  2681. "source": [
  2682. "conjugate(C)"
  2683. ]
  2684. },
  2685. {
  2686. "cell_type": "markdown",
  2687. "metadata": {},
  2688. "source": [
  2689. "厄米共轭:转置+共轭"
  2690. ]
  2691. },
  2692. {
  2693. "cell_type": "code",
  2694. "execution_count": 129,
  2695. "metadata": {},
  2696. "outputs": [
  2697. {
  2698. "data": {
  2699. "text/plain": [
  2700. "matrix([[0.-1.j, 0.-3.j],\n",
  2701. " [0.-2.j, 0.-4.j]])"
  2702. ]
  2703. },
  2704. "execution_count": 129,
  2705. "metadata": {},
  2706. "output_type": "execute_result"
  2707. }
  2708. ],
  2709. "source": [
  2710. "C.H"
  2711. ]
  2712. },
  2713. {
  2714. "cell_type": "markdown",
  2715. "metadata": {},
  2716. "source": [
  2717. "我们可以将复数数组的实部和虚部提取出来并用`real`和`imag`来表示:"
  2718. ]
  2719. },
  2720. {
  2721. "cell_type": "code",
  2722. "execution_count": 130,
  2723. "metadata": {},
  2724. "outputs": [
  2725. {
  2726. "data": {
  2727. "text/plain": [
  2728. "matrix([[0., 0.],\n",
  2729. " [0., 0.]])"
  2730. ]
  2731. },
  2732. "execution_count": 130,
  2733. "metadata": {},
  2734. "output_type": "execute_result"
  2735. }
  2736. ],
  2737. "source": [
  2738. "real(C) # same as: C.real"
  2739. ]
  2740. },
  2741. {
  2742. "cell_type": "code",
  2743. "execution_count": 131,
  2744. "metadata": {},
  2745. "outputs": [
  2746. {
  2747. "data": {
  2748. "text/plain": [
  2749. "matrix([[1., 2.],\n",
  2750. " [3., 4.]])"
  2751. ]
  2752. },
  2753. "execution_count": 131,
  2754. "metadata": {},
  2755. "output_type": "execute_result"
  2756. }
  2757. ],
  2758. "source": [
  2759. "imag(C) # same as: C.imag"
  2760. ]
  2761. },
  2762. {
  2763. "cell_type": "markdown",
  2764. "metadata": {},
  2765. "source": [
  2766. "或者说复数和绝对值"
  2767. ]
  2768. },
  2769. {
  2770. "cell_type": "code",
  2771. "execution_count": 106,
  2772. "metadata": {},
  2773. "outputs": [
  2774. {
  2775. "data": {
  2776. "text/plain": [
  2777. "array([[ 0.78539816, 1.10714872],\n",
  2778. " [ 1.24904577, 1.32581766]])"
  2779. ]
  2780. },
  2781. "execution_count": 106,
  2782. "metadata": {},
  2783. "output_type": "execute_result"
  2784. }
  2785. ],
  2786. "source": [
  2787. "angle(C+1) # heads up MATLAB Users, angle is used instead of arg"
  2788. ]
  2789. },
  2790. {
  2791. "cell_type": "code",
  2792. "execution_count": 107,
  2793. "metadata": {},
  2794. "outputs": [
  2795. {
  2796. "data": {
  2797. "text/plain": [
  2798. "matrix([[ 1., 2.],\n",
  2799. " [ 3., 4.]])"
  2800. ]
  2801. },
  2802. "execution_count": 107,
  2803. "metadata": {},
  2804. "output_type": "execute_result"
  2805. }
  2806. ],
  2807. "source": [
  2808. "abs(C)"
  2809. ]
  2810. },
  2811. {
  2812. "cell_type": "markdown",
  2813. "metadata": {},
  2814. "source": [
  2815. "### 矩阵计算"
  2816. ]
  2817. },
  2818. {
  2819. "cell_type": "markdown",
  2820. "metadata": {},
  2821. "source": [
  2822. "#### 求逆"
  2823. ]
  2824. },
  2825. {
  2826. "cell_type": "code",
  2827. "execution_count": 132,
  2828. "metadata": {},
  2829. "outputs": [
  2830. {
  2831. "data": {
  2832. "text/plain": [
  2833. "matrix([[0.+2.j , 0.-1.j ],\n",
  2834. " [0.-1.5j, 0.+0.5j]])"
  2835. ]
  2836. },
  2837. "execution_count": 132,
  2838. "metadata": {},
  2839. "output_type": "execute_result"
  2840. }
  2841. ],
  2842. "source": [
  2843. "np.linalg.inv(C) # equivalent to C.I "
  2844. ]
  2845. },
  2846. {
  2847. "cell_type": "code",
  2848. "execution_count": 133,
  2849. "metadata": {},
  2850. "outputs": [
  2851. {
  2852. "data": {
  2853. "text/plain": [
  2854. "matrix([[1.00000000e+00+0.j, 0.00000000e+00+0.j],\n",
  2855. " [2.22044605e-16+0.j, 1.00000000e+00+0.j]])"
  2856. ]
  2857. },
  2858. "execution_count": 133,
  2859. "metadata": {},
  2860. "output_type": "execute_result"
  2861. }
  2862. ],
  2863. "source": [
  2864. "C.I * C"
  2865. ]
  2866. },
  2867. {
  2868. "cell_type": "markdown",
  2869. "metadata": {},
  2870. "source": [
  2871. "#### 行列式"
  2872. ]
  2873. },
  2874. {
  2875. "cell_type": "code",
  2876. "execution_count": 134,
  2877. "metadata": {},
  2878. "outputs": [
  2879. {
  2880. "data": {
  2881. "text/plain": [
  2882. "(2.0000000000000004+0j)"
  2883. ]
  2884. },
  2885. "execution_count": 134,
  2886. "metadata": {},
  2887. "output_type": "execute_result"
  2888. }
  2889. ],
  2890. "source": [
  2891. "np.linalg.det(C)"
  2892. ]
  2893. },
  2894. {
  2895. "cell_type": "code",
  2896. "execution_count": 135,
  2897. "metadata": {},
  2898. "outputs": [
  2899. {
  2900. "data": {
  2901. "text/plain": [
  2902. "(0.49999999999999967+0j)"
  2903. ]
  2904. },
  2905. "execution_count": 135,
  2906. "metadata": {},
  2907. "output_type": "execute_result"
  2908. }
  2909. ],
  2910. "source": [
  2911. "linalg.det(C.I)"
  2912. ]
  2913. },
  2914. {
  2915. "cell_type": "markdown",
  2916. "metadata": {},
  2917. "source": [
  2918. "### 数据处理"
  2919. ]
  2920. },
  2921. {
  2922. "cell_type": "markdown",
  2923. "metadata": {},
  2924. "source": [
  2925. "通常将数据集存储在Numpy数组中是非常有用的。Numpy提供了许多函数用于计算数组中数据集的统计。\n",
  2926. "\n",
  2927. "例如,让我们从上面使用的斯德哥尔摩温度数据集计算一些属性。"
  2928. ]
  2929. },
  2930. {
  2931. "cell_type": "code",
  2932. "execution_count": 136,
  2933. "metadata": {},
  2934. "outputs": [
  2935. {
  2936. "data": {
  2937. "text/plain": [
  2938. "(77431, 7)"
  2939. ]
  2940. },
  2941. "execution_count": 136,
  2942. "metadata": {},
  2943. "output_type": "execute_result"
  2944. }
  2945. ],
  2946. "source": [
  2947. "# 提醒一下,温度数据集存储在数据变量中:\n",
  2948. "np.shape(data)"
  2949. ]
  2950. },
  2951. {
  2952. "cell_type": "markdown",
  2953. "metadata": {},
  2954. "source": [
  2955. "#### mean"
  2956. ]
  2957. },
  2958. {
  2959. "cell_type": "code",
  2960. "execution_count": 88,
  2961. "metadata": {},
  2962. "outputs": [
  2963. {
  2964. "name": "stdout",
  2965. "output_type": "stream",
  2966. "text": [
  2967. "(77431, 7)\n"
  2968. ]
  2969. },
  2970. {
  2971. "data": {
  2972. "text/plain": [
  2973. "6.197109684751585"
  2974. ]
  2975. },
  2976. "execution_count": 88,
  2977. "metadata": {},
  2978. "output_type": "execute_result"
  2979. }
  2980. ],
  2981. "source": [
  2982. "# 温度数据在第三列中\n",
  2983. "print(data.shape)\n",
  2984. "np.mean(data[:,3])"
  2985. ]
  2986. },
  2987. {
  2988. "cell_type": "code",
  2989. "execution_count": 137,
  2990. "metadata": {},
  2991. "outputs": [
  2992. {
  2993. "data": {
  2994. "text/plain": [
  2995. "0.4764047026464162"
  2996. ]
  2997. },
  2998. "execution_count": 137,
  2999. "metadata": {},
  3000. "output_type": "execute_result"
  3001. }
  3002. ],
  3003. "source": [
  3004. "A = np.random.rand(4, 3)\n",
  3005. "np.mean(A)"
  3006. ]
  3007. },
  3008. {
  3009. "cell_type": "markdown",
  3010. "metadata": {},
  3011. "source": [
  3012. "在过去的200年里,斯德哥尔摩每天的平均气温大约是6.2 C。"
  3013. ]
  3014. },
  3015. {
  3016. "cell_type": "markdown",
  3017. "metadata": {},
  3018. "source": [
  3019. "#### 标准差和方差"
  3020. ]
  3021. },
  3022. {
  3023. "cell_type": "code",
  3024. "execution_count": 138,
  3025. "metadata": {},
  3026. "outputs": [
  3027. {
  3028. "data": {
  3029. "text/plain": [
  3030. "(8.282271621340573, 68.59602320966341)"
  3031. ]
  3032. },
  3033. "execution_count": 138,
  3034. "metadata": {},
  3035. "output_type": "execute_result"
  3036. }
  3037. ],
  3038. "source": [
  3039. "np.std(data[:,3]), np.var(data[:,3])"
  3040. ]
  3041. },
  3042. {
  3043. "cell_type": "markdown",
  3044. "metadata": {},
  3045. "source": [
  3046. "#### 最小值和最大值"
  3047. ]
  3048. },
  3049. {
  3050. "cell_type": "code",
  3051. "execution_count": 139,
  3052. "metadata": {},
  3053. "outputs": [
  3054. {
  3055. "data": {
  3056. "text/plain": [
  3057. "-25.8"
  3058. ]
  3059. },
  3060. "execution_count": 139,
  3061. "metadata": {},
  3062. "output_type": "execute_result"
  3063. }
  3064. ],
  3065. "source": [
  3066. "# 最低日平均温度\n",
  3067. "data[:,3].min()"
  3068. ]
  3069. },
  3070. {
  3071. "cell_type": "code",
  3072. "execution_count": 140,
  3073. "metadata": {},
  3074. "outputs": [
  3075. {
  3076. "data": {
  3077. "text/plain": [
  3078. "28.3"
  3079. ]
  3080. },
  3081. "execution_count": 140,
  3082. "metadata": {},
  3083. "output_type": "execute_result"
  3084. }
  3085. ],
  3086. "source": [
  3087. "# 最高日平均温度\n",
  3088. "data[:,3].max()"
  3089. ]
  3090. },
  3091. {
  3092. "cell_type": "markdown",
  3093. "metadata": {},
  3094. "source": [
  3095. "#### sum, prod, and trace"
  3096. ]
  3097. },
  3098. {
  3099. "cell_type": "code",
  3100. "execution_count": 141,
  3101. "metadata": {},
  3102. "outputs": [
  3103. {
  3104. "data": {
  3105. "text/plain": [
  3106. "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
  3107. ]
  3108. },
  3109. "execution_count": 141,
  3110. "metadata": {},
  3111. "output_type": "execute_result"
  3112. }
  3113. ],
  3114. "source": [
  3115. "d = np.arange(0, 10)\n",
  3116. "d"
  3117. ]
  3118. },
  3119. {
  3120. "cell_type": "code",
  3121. "execution_count": 142,
  3122. "metadata": {},
  3123. "outputs": [
  3124. {
  3125. "data": {
  3126. "text/plain": [
  3127. "45"
  3128. ]
  3129. },
  3130. "execution_count": 142,
  3131. "metadata": {},
  3132. "output_type": "execute_result"
  3133. }
  3134. ],
  3135. "source": [
  3136. "# 将所有的元素相加\n",
  3137. "np.sum(d)"
  3138. ]
  3139. },
  3140. {
  3141. "cell_type": "code",
  3142. "execution_count": 143,
  3143. "metadata": {},
  3144. "outputs": [
  3145. {
  3146. "data": {
  3147. "text/plain": [
  3148. "3628800"
  3149. ]
  3150. },
  3151. "execution_count": 143,
  3152. "metadata": {},
  3153. "output_type": "execute_result"
  3154. }
  3155. ],
  3156. "source": [
  3157. "# 全元素积分\n",
  3158. "np.prod(d+1)"
  3159. ]
  3160. },
  3161. {
  3162. "cell_type": "code",
  3163. "execution_count": 144,
  3164. "metadata": {},
  3165. "outputs": [
  3166. {
  3167. "data": {
  3168. "text/plain": [
  3169. "array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45])"
  3170. ]
  3171. },
  3172. "execution_count": 144,
  3173. "metadata": {},
  3174. "output_type": "execute_result"
  3175. }
  3176. ],
  3177. "source": [
  3178. "# 累计求和\n",
  3179. "np.cumsum(d)"
  3180. ]
  3181. },
  3182. {
  3183. "cell_type": "code",
  3184. "execution_count": 147,
  3185. "metadata": {},
  3186. "outputs": [
  3187. {
  3188. "data": {
  3189. "text/plain": [
  3190. "array([ 1, 2, 6, 24, 120, 720, 5040,\n",
  3191. " 40320, 362880, 3628800])"
  3192. ]
  3193. },
  3194. "execution_count": 147,
  3195. "metadata": {},
  3196. "output_type": "execute_result"
  3197. }
  3198. ],
  3199. "source": [
  3200. "# 累计成绩\n",
  3201. "np.cumprod(d+1)"
  3202. ]
  3203. },
  3204. {
  3205. "cell_type": "code",
  3206. "execution_count": 148,
  3207. "metadata": {},
  3208. "outputs": [
  3209. {
  3210. "data": {
  3211. "text/plain": [
  3212. "1.04879166276667"
  3213. ]
  3214. },
  3215. "execution_count": 148,
  3216. "metadata": {},
  3217. "output_type": "execute_result"
  3218. }
  3219. ],
  3220. "source": [
  3221. "# 计算对角线元素的和,和diag(A).sum()一样\n",
  3222. "np.trace(A)"
  3223. ]
  3224. },
  3225. {
  3226. "cell_type": "markdown",
  3227. "metadata": {},
  3228. "source": [
  3229. "### 数组子集的计算"
  3230. ]
  3231. },
  3232. {
  3233. "cell_type": "markdown",
  3234. "metadata": {},
  3235. "source": [
  3236. "我们可以使用索引、花式索引和从数组中提取数据的其他方法(如上所述)来计算数组中的数据子集。\n",
  3237. "\n",
  3238. "例如,让我们回到温度数据集:"
  3239. ]
  3240. },
  3241. {
  3242. "cell_type": "code",
  3243. "execution_count": 149,
  3244. "metadata": {},
  3245. "outputs": [
  3246. {
  3247. "name": "stdout",
  3248. "output_type": "stream",
  3249. "text": [
  3250. "1800 1 1 -6.1 -6.1 -6.1 1\r\n",
  3251. "1800 1 2 -15.4 -15.4 -15.4 1\r\n",
  3252. "1800 1 3 -15.0 -15.0 -15.0 1\r\n"
  3253. ]
  3254. }
  3255. ],
  3256. "source": [
  3257. "!head -n 3 stockholm_td_adj.dat"
  3258. ]
  3259. },
  3260. {
  3261. "cell_type": "markdown",
  3262. "metadata": {},
  3263. "source": [
  3264. "数据集的格式是:年,月,日,日平均气温,低,高,位置。\n",
  3265. "\n",
  3266. "如果我们对某个特定月份的平均温度感兴趣,比如二月,然后我们可以创建一个索引掩码,使用它来选择当月的数据:"
  3267. ]
  3268. },
  3269. {
  3270. "cell_type": "code",
  3271. "execution_count": 99,
  3272. "metadata": {},
  3273. "outputs": [
  3274. {
  3275. "data": {
  3276. "text/plain": [
  3277. "array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.])"
  3278. ]
  3279. },
  3280. "execution_count": 99,
  3281. "metadata": {},
  3282. "output_type": "execute_result"
  3283. }
  3284. ],
  3285. "source": [
  3286. "np.unique(data[:,1]) # 列的值从1到12"
  3287. ]
  3288. },
  3289. {
  3290. "cell_type": "code",
  3291. "execution_count": 150,
  3292. "metadata": {},
  3293. "outputs": [
  3294. {
  3295. "name": "stdout",
  3296. "output_type": "stream",
  3297. "text": [
  3298. "[False False False ... False False False]\n"
  3299. ]
  3300. }
  3301. ],
  3302. "source": [
  3303. "mask_feb = data[:,1] == 2\n",
  3304. "print(mask_feb)"
  3305. ]
  3306. },
  3307. {
  3308. "cell_type": "code",
  3309. "execution_count": 151,
  3310. "metadata": {},
  3311. "outputs": [
  3312. {
  3313. "name": "stdout",
  3314. "output_type": "stream",
  3315. "text": [
  3316. "-3.212109570736596\n",
  3317. "5.090390768766271\n"
  3318. ]
  3319. }
  3320. ],
  3321. "source": [
  3322. "# 温度数据实在第三行\n",
  3323. "print(np.mean(data[mask_feb,3]))\n",
  3324. "print(np.std(data[mask_feb,3]))"
  3325. ]
  3326. },
  3327. {
  3328. "cell_type": "markdown",
  3329. "metadata": {},
  3330. "source": [
  3331. "有了这些工具,我们就有了非常强大的数据处理能力。例如,提取每年每个月的平均气温只需要几行代码:"
  3332. ]
  3333. },
  3334. {
  3335. "cell_type": "code",
  3336. "execution_count": 153,
  3337. "metadata": {},
  3338. "outputs": [
  3339. {
  3340. "data": {
  3341. "image/png": "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\n",
  3342. "text/plain": [
  3343. "<Figure size 432x288 with 1 Axes>"
  3344. ]
  3345. },
  3346. "metadata": {
  3347. "needs_background": "light"
  3348. },
  3349. "output_type": "display_data"
  3350. }
  3351. ],
  3352. "source": [
  3353. "months = np.arange(1,13)\n",
  3354. "monthly_mean = [np.mean(data[data[:,1] == month, 3]) for month in months]\n",
  3355. "\n",
  3356. "fig, ax = plt.subplots()\n",
  3357. "ax.bar(months, monthly_mean)\n",
  3358. "ax.set_xlabel(\"Month\")\n",
  3359. "ax.set_ylabel(\"Monthly avg. temp.\");"
  3360. ]
  3361. },
  3362. {
  3363. "cell_type": "markdown",
  3364. "metadata": {},
  3365. "source": [
  3366. "### 高维数据的计算"
  3367. ]
  3368. },
  3369. {
  3370. "cell_type": "markdown",
  3371. "metadata": {},
  3372. "source": [
  3373. "当例如`min`, `max`等函数应用在高维数组上时,有时将计算应用于整个数组是有用的,而且很多时候有时只基于行或列。用`axis`参数我们可以决定这个函数应该怎样表现:"
  3374. ]
  3375. },
  3376. {
  3377. "cell_type": "code",
  3378. "execution_count": 157,
  3379. "metadata": {},
  3380. "outputs": [
  3381. {
  3382. "data": {
  3383. "text/plain": [
  3384. "array([[0.99782852, 0.15992805, 0.31262638],\n",
  3385. " [0.51702607, 0.45658172, 0.66789036],\n",
  3386. " [0.77771351, 0.42574723, 0.14011317]])"
  3387. ]
  3388. },
  3389. "execution_count": 157,
  3390. "metadata": {},
  3391. "output_type": "execute_result"
  3392. }
  3393. ],
  3394. "source": [
  3395. "import numpy as np\n",
  3396. "\n",
  3397. "m = np.random.rand(3,3)\n",
  3398. "m"
  3399. ]
  3400. },
  3401. {
  3402. "cell_type": "code",
  3403. "execution_count": 158,
  3404. "metadata": {},
  3405. "outputs": [
  3406. {
  3407. "data": {
  3408. "text/plain": [
  3409. "0.997828517861979"
  3410. ]
  3411. },
  3412. "execution_count": 158,
  3413. "metadata": {},
  3414. "output_type": "execute_result"
  3415. }
  3416. ],
  3417. "source": [
  3418. "# global max\n",
  3419. "m.max()"
  3420. ]
  3421. },
  3422. {
  3423. "cell_type": "code",
  3424. "execution_count": 159,
  3425. "metadata": {},
  3426. "outputs": [
  3427. {
  3428. "data": {
  3429. "text/plain": [
  3430. "array([0.99782852, 0.45658172, 0.66789036])"
  3431. ]
  3432. },
  3433. "execution_count": 159,
  3434. "metadata": {},
  3435. "output_type": "execute_result"
  3436. }
  3437. ],
  3438. "source": [
  3439. "# max in each column\n",
  3440. "m.max(axis=0)"
  3441. ]
  3442. },
  3443. {
  3444. "cell_type": "code",
  3445. "execution_count": 160,
  3446. "metadata": {},
  3447. "outputs": [
  3448. {
  3449. "data": {
  3450. "text/plain": [
  3451. "array([0.99782852, 0.66789036, 0.77771351])"
  3452. ]
  3453. },
  3454. "execution_count": 160,
  3455. "metadata": {},
  3456. "output_type": "execute_result"
  3457. }
  3458. ],
  3459. "source": [
  3460. "# max in each row\n",
  3461. "m.max(axis=1)"
  3462. ]
  3463. },
  3464. {
  3465. "cell_type": "markdown",
  3466. "metadata": {},
  3467. "source": [
  3468. "许多其他的在`array` 和`matrix`类中的函数和方法接受同样(可选的)的关键字参数`axis`"
  3469. ]
  3470. },
  3471. {
  3472. "cell_type": "markdown",
  3473. "metadata": {},
  3474. "source": [
  3475. "## 阵列的重塑、调整大小和堆叠"
  3476. ]
  3477. },
  3478. {
  3479. "cell_type": "markdown",
  3480. "metadata": {},
  3481. "source": [
  3482. "Numpy数组的形状可以被确定而无需复制底层数据,这使得即使对于大型数组也能有较快的操作。"
  3483. ]
  3484. },
  3485. {
  3486. "cell_type": "code",
  3487. "execution_count": 162,
  3488. "metadata": {},
  3489. "outputs": [
  3490. {
  3491. "name": "stdout",
  3492. "output_type": "stream",
  3493. "text": [
  3494. "[[0.97579482 0.78668761 0.61373444]\n",
  3495. " [0.58850244 0.9784108 0.08465447]\n",
  3496. " [0.57262123 0.44795615 0.75564229]\n",
  3497. " [0.36770219 0.34095592 0.16259103]]\n"
  3498. ]
  3499. }
  3500. ],
  3501. "source": [
  3502. "import numpy as np\n",
  3503. "\n",
  3504. "A = np.random.rand(4, 3)\n",
  3505. "print(A)"
  3506. ]
  3507. },
  3508. {
  3509. "cell_type": "code",
  3510. "execution_count": 163,
  3511. "metadata": {},
  3512. "outputs": [
  3513. {
  3514. "name": "stdout",
  3515. "output_type": "stream",
  3516. "text": [
  3517. "4 3\n"
  3518. ]
  3519. }
  3520. ],
  3521. "source": [
  3522. "n, m = A.shape\n",
  3523. "print(n, m)"
  3524. ]
  3525. },
  3526. {
  3527. "cell_type": "code",
  3528. "execution_count": 166,
  3529. "metadata": {},
  3530. "outputs": [
  3531. {
  3532. "data": {
  3533. "text/plain": [
  3534. "array([[0.97579482, 0.78668761, 0.61373444, 0.58850244, 0.9784108 ,\n",
  3535. " 0.08465447, 0.57262123, 0.44795615, 0.75564229, 0.36770219,\n",
  3536. " 0.34095592, 0.16259103]])"
  3537. ]
  3538. },
  3539. "execution_count": 166,
  3540. "metadata": {},
  3541. "output_type": "execute_result"
  3542. }
  3543. ],
  3544. "source": [
  3545. "B = A.reshape((1,n*m))\n",
  3546. "B"
  3547. ]
  3548. },
  3549. {
  3550. "cell_type": "code",
  3551. "execution_count": 167,
  3552. "metadata": {},
  3553. "outputs": [
  3554. {
  3555. "name": "stdout",
  3556. "output_type": "stream",
  3557. "text": [
  3558. "[[0.97579482]\n",
  3559. " [0.78668761]\n",
  3560. " [0.61373444]\n",
  3561. " [0.58850244]\n",
  3562. " [0.9784108 ]\n",
  3563. " [0.08465447]\n",
  3564. " [0.57262123]\n",
  3565. " [0.44795615]\n",
  3566. " [0.75564229]\n",
  3567. " [0.36770219]\n",
  3568. " [0.34095592]\n",
  3569. " [0.16259103]]\n"
  3570. ]
  3571. }
  3572. ],
  3573. "source": [
  3574. "B2 = A.reshape((n*m, 1))\n",
  3575. "print(B2)"
  3576. ]
  3577. },
  3578. {
  3579. "cell_type": "code",
  3580. "execution_count": 168,
  3581. "metadata": {},
  3582. "outputs": [
  3583. {
  3584. "data": {
  3585. "text/plain": [
  3586. "array([[5. , 5. , 5. , 5. , 5. ,\n",
  3587. " 0.08465447, 0.57262123, 0.44795615, 0.75564229, 0.36770219,\n",
  3588. " 0.34095592, 0.16259103]])"
  3589. ]
  3590. },
  3591. "execution_count": 168,
  3592. "metadata": {},
  3593. "output_type": "execute_result"
  3594. }
  3595. ],
  3596. "source": [
  3597. "B[0,0:5] = 5 # modify the array\n",
  3598. "\n",
  3599. "B"
  3600. ]
  3601. },
  3602. {
  3603. "cell_type": "code",
  3604. "execution_count": 169,
  3605. "metadata": {},
  3606. "outputs": [
  3607. {
  3608. "data": {
  3609. "text/plain": [
  3610. "array([[5. , 5. , 5. ],\n",
  3611. " [5. , 5. , 0.08465447],\n",
  3612. " [0.57262123, 0.44795615, 0.75564229],\n",
  3613. " [0.36770219, 0.34095592, 0.16259103]])"
  3614. ]
  3615. },
  3616. "execution_count": 169,
  3617. "metadata": {},
  3618. "output_type": "execute_result"
  3619. }
  3620. ],
  3621. "source": [
  3622. "A # and the original variable is also changed. B is only a different view of the same data"
  3623. ]
  3624. },
  3625. {
  3626. "cell_type": "markdown",
  3627. "metadata": {},
  3628. "source": [
  3629. "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."
  3630. ]
  3631. },
  3632. {
  3633. "cell_type": "code",
  3634. "execution_count": 170,
  3635. "metadata": {},
  3636. "outputs": [
  3637. {
  3638. "data": {
  3639. "text/plain": [
  3640. "array([5. , 5. , 5. , 5. , 5. ,\n",
  3641. " 0.08465447, 0.57262123, 0.44795615, 0.75564229, 0.36770219,\n",
  3642. " 0.34095592, 0.16259103])"
  3643. ]
  3644. },
  3645. "execution_count": 170,
  3646. "metadata": {},
  3647. "output_type": "execute_result"
  3648. }
  3649. ],
  3650. "source": [
  3651. "B = A.flatten()\n",
  3652. "\n",
  3653. "B"
  3654. ]
  3655. },
  3656. {
  3657. "cell_type": "code",
  3658. "execution_count": 171,
  3659. "metadata": {},
  3660. "outputs": [
  3661. {
  3662. "name": "stdout",
  3663. "output_type": "stream",
  3664. "text": [
  3665. "(12,)\n"
  3666. ]
  3667. }
  3668. ],
  3669. "source": [
  3670. "print(B.shape)"
  3671. ]
  3672. },
  3673. {
  3674. "cell_type": "code",
  3675. "execution_count": 172,
  3676. "metadata": {},
  3677. "outputs": [
  3678. {
  3679. "name": "stdout",
  3680. "output_type": "stream",
  3681. "text": [
  3682. "[0.0643267 0.02070895 0.01127191 0.36318507 0.26309744 0.8332378\n",
  3683. " 0.79477743 0.52745619 0.35675021 0.55907373 0.18993756 0.15919449\n",
  3684. " 0.54789401 0.23186893 0.02898541 0.43545343 0.80684175 0.44014057\n",
  3685. " 0.05129167 0.95111801 0.40743132 0.57197596 0.6692788 0.80824496\n",
  3686. " 0.40301441 0.84369196 0.95294593 0.14876807 0.58005171 0.30849079\n",
  3687. " 0.27846197 0.01062528 0.62870079 0.6416306 0.76945123 0.39443503\n",
  3688. " 0.76619764 0.42833327 0.60720341 0.16246792 0.76067082 0.27134944\n",
  3689. " 0.36268568 0.78501742 0.36935191 0.43410334 0.10594888 0.12941728\n",
  3690. " 0.51760718 0.57260509 0.09756568 0.13216908 0.32918105 0.9338644\n",
  3691. " 0.71681907 0.58218819 0.58798528 0.81665138 0.73604797 0.91730101]\n"
  3692. ]
  3693. }
  3694. ],
  3695. "source": [
  3696. "T = np.random.rand(3, 4, 5)\n",
  3697. "T2 = T.flatten()\n",
  3698. "print(T2)"
  3699. ]
  3700. },
  3701. {
  3702. "cell_type": "code",
  3703. "execution_count": 176,
  3704. "metadata": {},
  3705. "outputs": [
  3706. {
  3707. "data": {
  3708. "text/plain": [
  3709. "array([10. , 10. , 10. , 10. , 10. ,\n",
  3710. " 0.08465447, 0.57262123, 0.44795615, 0.75564229, 0.36770219,\n",
  3711. " 0.34095592, 0.16259103])"
  3712. ]
  3713. },
  3714. "execution_count": 176,
  3715. "metadata": {},
  3716. "output_type": "execute_result"
  3717. }
  3718. ],
  3719. "source": [
  3720. "B[0:5] = 10\n",
  3721. "\n",
  3722. "B"
  3723. ]
  3724. },
  3725. {
  3726. "cell_type": "code",
  3727. "execution_count": 177,
  3728. "metadata": {},
  3729. "outputs": [
  3730. {
  3731. "data": {
  3732. "text/plain": [
  3733. "array([[5. , 5. , 5. ],\n",
  3734. " [5. , 5. , 0.08465447],\n",
  3735. " [0.57262123, 0.44795615, 0.75564229],\n",
  3736. " [0.36770219, 0.34095592, 0.16259103]])"
  3737. ]
  3738. },
  3739. "execution_count": 177,
  3740. "metadata": {},
  3741. "output_type": "execute_result"
  3742. }
  3743. ],
  3744. "source": [
  3745. "A # 现在A并没有改变,因为B的数值是A的复制,并不指向同样的值。"
  3746. ]
  3747. },
  3748. {
  3749. "cell_type": "markdown",
  3750. "metadata": {},
  3751. "source": [
  3752. "## 添加新的维度:newaxis"
  3753. ]
  3754. },
  3755. {
  3756. "cell_type": "markdown",
  3757. "metadata": {},
  3758. "source": [
  3759. "有了`newaxis`,我们可以在数组中插入新的维度,例如将一个向量转换为列或行矩阵:"
  3760. ]
  3761. },
  3762. {
  3763. "cell_type": "code",
  3764. "execution_count": 178,
  3765. "metadata": {},
  3766. "outputs": [],
  3767. "source": [
  3768. "v = np.array([1,2,3])"
  3769. ]
  3770. },
  3771. {
  3772. "cell_type": "code",
  3773. "execution_count": 179,
  3774. "metadata": {},
  3775. "outputs": [
  3776. {
  3777. "data": {
  3778. "text/plain": [
  3779. "(3,)"
  3780. ]
  3781. },
  3782. "execution_count": 179,
  3783. "metadata": {},
  3784. "output_type": "execute_result"
  3785. }
  3786. ],
  3787. "source": [
  3788. "np.shape(v)"
  3789. ]
  3790. },
  3791. {
  3792. "cell_type": "code",
  3793. "execution_count": 180,
  3794. "metadata": {},
  3795. "outputs": [
  3796. {
  3797. "name": "stdout",
  3798. "output_type": "stream",
  3799. "text": [
  3800. "[1 2 3]\n"
  3801. ]
  3802. }
  3803. ],
  3804. "source": [
  3805. "print(v)"
  3806. ]
  3807. },
  3808. {
  3809. "cell_type": "code",
  3810. "execution_count": 182,
  3811. "metadata": {},
  3812. "outputs": [
  3813. {
  3814. "name": "stdout",
  3815. "output_type": "stream",
  3816. "text": [
  3817. "(3, 1)\n"
  3818. ]
  3819. }
  3820. ],
  3821. "source": [
  3822. "v2 = v.reshape(3, 1)\n",
  3823. "print(v2.shape)"
  3824. ]
  3825. },
  3826. {
  3827. "cell_type": "code",
  3828. "execution_count": 190,
  3829. "metadata": {},
  3830. "outputs": [
  3831. {
  3832. "name": "stdout",
  3833. "output_type": "stream",
  3834. "text": [
  3835. "(3,)\n",
  3836. "(3, 1)\n"
  3837. ]
  3838. }
  3839. ],
  3840. "source": [
  3841. "# 做一个向量v的列矩阵\n",
  3842. "v2 = v[:, np.newaxis]\n",
  3843. "print(v.shape)\n",
  3844. "print(v2.shape)\n"
  3845. ]
  3846. },
  3847. {
  3848. "cell_type": "code",
  3849. "execution_count": 191,
  3850. "metadata": {},
  3851. "outputs": [
  3852. {
  3853. "data": {
  3854. "text/plain": [
  3855. "(3, 1)"
  3856. ]
  3857. },
  3858. "execution_count": 191,
  3859. "metadata": {},
  3860. "output_type": "execute_result"
  3861. }
  3862. ],
  3863. "source": [
  3864. "# 列矩阵\n",
  3865. "v[:,newaxis].shape"
  3866. ]
  3867. },
  3868. {
  3869. "cell_type": "code",
  3870. "execution_count": 144,
  3871. "metadata": {},
  3872. "outputs": [
  3873. {
  3874. "data": {
  3875. "text/plain": [
  3876. "(1, 3)"
  3877. ]
  3878. },
  3879. "execution_count": 144,
  3880. "metadata": {},
  3881. "output_type": "execute_result"
  3882. }
  3883. ],
  3884. "source": [
  3885. "# 行矩阵\n",
  3886. "v[newaxis,:].shape"
  3887. ]
  3888. },
  3889. {
  3890. "cell_type": "markdown",
  3891. "metadata": {},
  3892. "source": [
  3893. "## 叠加和重复数组"
  3894. ]
  3895. },
  3896. {
  3897. "cell_type": "markdown",
  3898. "metadata": {},
  3899. "source": [
  3900. "利用函数`repeat`, `tile`, `vstack`, `hstack`, 和`concatenate` 我们可以用较小的向量和矩阵来创建更大的向量和矩阵:"
  3901. ]
  3902. },
  3903. {
  3904. "cell_type": "markdown",
  3905. "metadata": {},
  3906. "source": [
  3907. "### tile and repeat"
  3908. ]
  3909. },
  3910. {
  3911. "cell_type": "code",
  3912. "execution_count": 192,
  3913. "metadata": {},
  3914. "outputs": [],
  3915. "source": [
  3916. "a = np.array([[1, 2], [3, 4]])"
  3917. ]
  3918. },
  3919. {
  3920. "cell_type": "code",
  3921. "execution_count": 194,
  3922. "metadata": {},
  3923. "outputs": [
  3924. {
  3925. "name": "stdout",
  3926. "output_type": "stream",
  3927. "text": [
  3928. "[[1 2]\n",
  3929. " [3 4]]\n"
  3930. ]
  3931. },
  3932. {
  3933. "data": {
  3934. "text/plain": [
  3935. "array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])"
  3936. ]
  3937. },
  3938. "execution_count": 194,
  3939. "metadata": {},
  3940. "output_type": "execute_result"
  3941. }
  3942. ],
  3943. "source": [
  3944. "print(a)\n",
  3945. "\n",
  3946. "# 重复每一个元素三次\n",
  3947. "np.repeat(a, 3)"
  3948. ]
  3949. },
  3950. {
  3951. "cell_type": "code",
  3952. "execution_count": 195,
  3953. "metadata": {},
  3954. "outputs": [
  3955. {
  3956. "data": {
  3957. "text/plain": [
  3958. "array([[1, 2, 1, 2, 1, 2],\n",
  3959. " [3, 4, 3, 4, 3, 4]])"
  3960. ]
  3961. },
  3962. "execution_count": 195,
  3963. "metadata": {},
  3964. "output_type": "execute_result"
  3965. }
  3966. ],
  3967. "source": [
  3968. "# tile the matrix 3 times \n",
  3969. "np.tile(a, 3)"
  3970. ]
  3971. },
  3972. {
  3973. "cell_type": "code",
  3974. "execution_count": 196,
  3975. "metadata": {},
  3976. "outputs": [
  3977. {
  3978. "data": {
  3979. "text/plain": [
  3980. "array([[1, 2, 1, 2, 1, 2],\n",
  3981. " [3, 4, 3, 4, 3, 4]])"
  3982. ]
  3983. },
  3984. "execution_count": 196,
  3985. "metadata": {},
  3986. "output_type": "execute_result"
  3987. }
  3988. ],
  3989. "source": [
  3990. "# 更好的方案\n",
  3991. "np.tile(a, (1, 3))"
  3992. ]
  3993. },
  3994. {
  3995. "cell_type": "code",
  3996. "execution_count": 34,
  3997. "metadata": {},
  3998. "outputs": [
  3999. {
  4000. "data": {
  4001. "text/plain": [
  4002. "array([[1, 2],\n",
  4003. " [3, 4],\n",
  4004. " [1, 2],\n",
  4005. " [3, 4],\n",
  4006. " [1, 2],\n",
  4007. " [3, 4]])"
  4008. ]
  4009. },
  4010. "execution_count": 34,
  4011. "metadata": {},
  4012. "output_type": "execute_result"
  4013. }
  4014. ],
  4015. "source": [
  4016. "np.tile(a, (3, 1))"
  4017. ]
  4018. },
  4019. {
  4020. "cell_type": "markdown",
  4021. "metadata": {},
  4022. "source": [
  4023. "### concatenate"
  4024. ]
  4025. },
  4026. {
  4027. "cell_type": "code",
  4028. "execution_count": 197,
  4029. "metadata": {},
  4030. "outputs": [],
  4031. "source": [
  4032. "b = np.array([[5, 6]])"
  4033. ]
  4034. },
  4035. {
  4036. "cell_type": "code",
  4037. "execution_count": 198,
  4038. "metadata": {},
  4039. "outputs": [
  4040. {
  4041. "data": {
  4042. "text/plain": [
  4043. "array([[1, 2],\n",
  4044. " [3, 4],\n",
  4045. " [5, 6]])"
  4046. ]
  4047. },
  4048. "execution_count": 198,
  4049. "metadata": {},
  4050. "output_type": "execute_result"
  4051. }
  4052. ],
  4053. "source": [
  4054. "np.concatenate((a, b), axis=0)"
  4055. ]
  4056. },
  4057. {
  4058. "cell_type": "code",
  4059. "execution_count": 200,
  4060. "metadata": {},
  4061. "outputs": [
  4062. {
  4063. "data": {
  4064. "text/plain": [
  4065. "array([[1, 2, 5],\n",
  4066. " [3, 4, 6]])"
  4067. ]
  4068. },
  4069. "execution_count": 200,
  4070. "metadata": {},
  4071. "output_type": "execute_result"
  4072. }
  4073. ],
  4074. "source": [
  4075. "np.concatenate((a, b.T), axis=1)"
  4076. ]
  4077. },
  4078. {
  4079. "cell_type": "markdown",
  4080. "metadata": {},
  4081. "source": [
  4082. "### hstack and vstack"
  4083. ]
  4084. },
  4085. {
  4086. "cell_type": "code",
  4087. "execution_count": 201,
  4088. "metadata": {},
  4089. "outputs": [
  4090. {
  4091. "data": {
  4092. "text/plain": [
  4093. "array([[1, 2],\n",
  4094. " [3, 4],\n",
  4095. " [5, 6]])"
  4096. ]
  4097. },
  4098. "execution_count": 201,
  4099. "metadata": {},
  4100. "output_type": "execute_result"
  4101. }
  4102. ],
  4103. "source": [
  4104. "np.vstack((a,b))"
  4105. ]
  4106. },
  4107. {
  4108. "cell_type": "code",
  4109. "execution_count": 202,
  4110. "metadata": {},
  4111. "outputs": [
  4112. {
  4113. "data": {
  4114. "text/plain": [
  4115. "array([[1, 2, 5],\n",
  4116. " [3, 4, 6]])"
  4117. ]
  4118. },
  4119. "execution_count": 202,
  4120. "metadata": {},
  4121. "output_type": "execute_result"
  4122. }
  4123. ],
  4124. "source": [
  4125. "np.hstack((a,b.T))"
  4126. ]
  4127. },
  4128. {
  4129. "cell_type": "markdown",
  4130. "metadata": {},
  4131. "source": [
  4132. "## 复制和“深度复制”"
  4133. ]
  4134. },
  4135. {
  4136. "cell_type": "markdown",
  4137. "metadata": {},
  4138. "source": [
  4139. "为了获得高性能,Python中的赋值通常不复制底层对象。例如,在函数之间传递对象时,这一点非常重要,以避免不必要时大量的内存复制(技术术语:通过引用传递)。"
  4140. ]
  4141. },
  4142. {
  4143. "cell_type": "code",
  4144. "execution_count": 203,
  4145. "metadata": {},
  4146. "outputs": [
  4147. {
  4148. "data": {
  4149. "text/plain": [
  4150. "array([[1, 2],\n",
  4151. " [3, 4]])"
  4152. ]
  4153. },
  4154. "execution_count": 203,
  4155. "metadata": {},
  4156. "output_type": "execute_result"
  4157. }
  4158. ],
  4159. "source": [
  4160. "A = np.array([[1, 2], [3, 4]])\n",
  4161. "\n",
  4162. "A"
  4163. ]
  4164. },
  4165. {
  4166. "cell_type": "code",
  4167. "execution_count": 204,
  4168. "metadata": {},
  4169. "outputs": [],
  4170. "source": [
  4171. "# 现在B和A指的是同一个数组数据\n",
  4172. "B = A "
  4173. ]
  4174. },
  4175. {
  4176. "cell_type": "code",
  4177. "execution_count": 205,
  4178. "metadata": {},
  4179. "outputs": [
  4180. {
  4181. "data": {
  4182. "text/plain": [
  4183. "array([[10, 2],\n",
  4184. " [ 3, 4]])"
  4185. ]
  4186. },
  4187. "execution_count": 205,
  4188. "metadata": {},
  4189. "output_type": "execute_result"
  4190. }
  4191. ],
  4192. "source": [
  4193. "# 改变B影响A\n",
  4194. "B[0,0] = 10\n",
  4195. "\n",
  4196. "B"
  4197. ]
  4198. },
  4199. {
  4200. "cell_type": "code",
  4201. "execution_count": 206,
  4202. "metadata": {},
  4203. "outputs": [
  4204. {
  4205. "data": {
  4206. "text/plain": [
  4207. "array([[10, 2],\n",
  4208. " [ 3, 4]])"
  4209. ]
  4210. },
  4211. "execution_count": 206,
  4212. "metadata": {},
  4213. "output_type": "execute_result"
  4214. }
  4215. ],
  4216. "source": [
  4217. "A"
  4218. ]
  4219. },
  4220. {
  4221. "cell_type": "markdown",
  4222. "metadata": {},
  4223. "source": [
  4224. "如果我们想避免这种行为,那么当我们从`A`中复制一个新的完全独立的对象`B`时,我们需要使用函数`copy`来做一个所谓的“深度复制”:"
  4225. ]
  4226. },
  4227. {
  4228. "cell_type": "code",
  4229. "execution_count": 207,
  4230. "metadata": {},
  4231. "outputs": [],
  4232. "source": [
  4233. "B = np.copy(A)"
  4234. ]
  4235. },
  4236. {
  4237. "cell_type": "code",
  4238. "execution_count": 208,
  4239. "metadata": {},
  4240. "outputs": [
  4241. {
  4242. "data": {
  4243. "text/plain": [
  4244. "array([[-5, 2],\n",
  4245. " [ 3, 4]])"
  4246. ]
  4247. },
  4248. "execution_count": 208,
  4249. "metadata": {},
  4250. "output_type": "execute_result"
  4251. }
  4252. ],
  4253. "source": [
  4254. "# 现在如果我们改变B,A不受影响\n",
  4255. "B[0,0] = -5\n",
  4256. "\n",
  4257. "B"
  4258. ]
  4259. },
  4260. {
  4261. "cell_type": "code",
  4262. "execution_count": 209,
  4263. "metadata": {},
  4264. "outputs": [
  4265. {
  4266. "data": {
  4267. "text/plain": [
  4268. "array([[10, 2],\n",
  4269. " [ 3, 4]])"
  4270. ]
  4271. },
  4272. "execution_count": 209,
  4273. "metadata": {},
  4274. "output_type": "execute_result"
  4275. }
  4276. ],
  4277. "source": [
  4278. "A"
  4279. ]
  4280. },
  4281. {
  4282. "cell_type": "markdown",
  4283. "metadata": {},
  4284. "source": [
  4285. "## 遍历数组元素"
  4286. ]
  4287. },
  4288. {
  4289. "cell_type": "markdown",
  4290. "metadata": {},
  4291. "source": [
  4292. "通常,我们希望尽可能避免遍历数组元素(不惜一切代价)。原因是在像Python(或MATLAB)这样的解释语言中,迭代与向量化操作相比真的很慢。\n",
  4293. "\n",
  4294. "然而,有时迭代是不可避免的。对于这种情况,Python的For循环是最方便的遍历数组的方法:"
  4295. ]
  4296. },
  4297. {
  4298. "cell_type": "code",
  4299. "execution_count": 210,
  4300. "metadata": {},
  4301. "outputs": [
  4302. {
  4303. "name": "stdout",
  4304. "output_type": "stream",
  4305. "text": [
  4306. "1\n",
  4307. "2\n",
  4308. "3\n",
  4309. "4\n"
  4310. ]
  4311. }
  4312. ],
  4313. "source": [
  4314. "v = np.array([1,2,3,4])\n",
  4315. "\n",
  4316. "for element in v:\n",
  4317. " print(element)"
  4318. ]
  4319. },
  4320. {
  4321. "cell_type": "code",
  4322. "execution_count": 211,
  4323. "metadata": {},
  4324. "outputs": [
  4325. {
  4326. "name": "stdout",
  4327. "output_type": "stream",
  4328. "text": [
  4329. "row [1 2]\n",
  4330. "1\n",
  4331. "2\n",
  4332. "row [3 4]\n",
  4333. "3\n",
  4334. "4\n"
  4335. ]
  4336. }
  4337. ],
  4338. "source": [
  4339. "M = np.array([[1,2], [3,4]])\n",
  4340. "\n",
  4341. "for row in M:\n",
  4342. " print(\"row\", row)\n",
  4343. " \n",
  4344. " for element in row:\n",
  4345. " print(element)"
  4346. ]
  4347. },
  4348. {
  4349. "cell_type": "markdown",
  4350. "metadata": {},
  4351. "source": [
  4352. "当我们需要去\n",
  4353. "当我们需要遍历一个数组的每个元素并修改它的元素时,使用`enumerate`函数可以方便地在`for`循环中获得元素及其索引:"
  4354. ]
  4355. },
  4356. {
  4357. "cell_type": "code",
  4358. "execution_count": 162,
  4359. "metadata": {},
  4360. "outputs": [
  4361. {
  4362. "name": "stdout",
  4363. "output_type": "stream",
  4364. "text": [
  4365. "('row_idx', 0, 'row', array([1, 2]))\n",
  4366. "('col_idx', 0, 'element', 1)\n",
  4367. "('col_idx', 1, 'element', 2)\n",
  4368. "('row_idx', 1, 'row', array([3, 4]))\n",
  4369. "('col_idx', 0, 'element', 3)\n",
  4370. "('col_idx', 1, 'element', 4)\n"
  4371. ]
  4372. }
  4373. ],
  4374. "source": [
  4375. "for row_idx, row in enumerate(M):\n",
  4376. " print(\"row_idx\", row_idx, \"row\", row)\n",
  4377. " \n",
  4378. " for col_idx, element in enumerate(row):\n",
  4379. " print(\"col_idx\", col_idx, \"element\", element)\n",
  4380. " \n",
  4381. " # update the matrix M: square each element\n",
  4382. " M[row_idx, col_idx] = element ** 2"
  4383. ]
  4384. },
  4385. {
  4386. "cell_type": "code",
  4387. "execution_count": 163,
  4388. "metadata": {},
  4389. "outputs": [
  4390. {
  4391. "data": {
  4392. "text/plain": [
  4393. "array([[ 1, 4],\n",
  4394. " [ 9, 16]])"
  4395. ]
  4396. },
  4397. "execution_count": 163,
  4398. "metadata": {},
  4399. "output_type": "execute_result"
  4400. }
  4401. ],
  4402. "source": [
  4403. "# each element in M is now squared\n",
  4404. "M"
  4405. ]
  4406. },
  4407. {
  4408. "cell_type": "markdown",
  4409. "metadata": {},
  4410. "source": [
  4411. "## Vectorizing functions"
  4412. ]
  4413. },
  4414. {
  4415. "cell_type": "markdown",
  4416. "metadata": {},
  4417. "source": [
  4418. "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."
  4419. ]
  4420. },
  4421. {
  4422. "cell_type": "code",
  4423. "execution_count": 213,
  4424. "metadata": {},
  4425. "outputs": [],
  4426. "source": [
  4427. "def Theta(x):\n",
  4428. " \"\"\"\n",
  4429. " Scalar implemenation of the Heaviside step function.\n",
  4430. " \"\"\"\n",
  4431. " if x >= 0:\n",
  4432. " return 1\n",
  4433. " else:\n",
  4434. " return 0"
  4435. ]
  4436. },
  4437. {
  4438. "cell_type": "code",
  4439. "execution_count": 214,
  4440. "metadata": {},
  4441. "outputs": [
  4442. {
  4443. "ename": "ValueError",
  4444. "evalue": "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()",
  4445. "output_type": "error",
  4446. "traceback": [
  4447. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  4448. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  4449. "\u001b[0;32m<ipython-input-214-2cb2062a7e18>\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",
  4450. "\u001b[0;32m<ipython-input-213-f72d7f42be84>\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",
  4451. "\u001b[0;31mValueError\u001b[0m: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"
  4452. ]
  4453. }
  4454. ],
  4455. "source": [
  4456. "Theta(array([-3,-2,-1,0,1,2,3]))"
  4457. ]
  4458. },
  4459. {
  4460. "cell_type": "markdown",
  4461. "metadata": {},
  4462. "source": [
  4463. "OK, that didn't work because we didn't write the `Theta` function so that it can handle a vector input... \n",
  4464. "\n",
  4465. "To get a vectorized version of Theta we can use the Numpy function `vectorize`. In many cases it can automatically vectorize a function:"
  4466. ]
  4467. },
  4468. {
  4469. "cell_type": "code",
  4470. "execution_count": 215,
  4471. "metadata": {},
  4472. "outputs": [],
  4473. "source": [
  4474. "Theta_vec = np.vectorize(Theta)"
  4475. ]
  4476. },
  4477. {
  4478. "cell_type": "code",
  4479. "execution_count": 216,
  4480. "metadata": {},
  4481. "outputs": [
  4482. {
  4483. "data": {
  4484. "text/plain": [
  4485. "array([0, 0, 0, 1, 1, 1, 1])"
  4486. ]
  4487. },
  4488. "execution_count": 216,
  4489. "metadata": {},
  4490. "output_type": "execute_result"
  4491. }
  4492. ],
  4493. "source": [
  4494. "Theta_vec(np.array([-3,-2,-1,0,1,2,3]))"
  4495. ]
  4496. },
  4497. {
  4498. "cell_type": "markdown",
  4499. "metadata": {},
  4500. "source": [
  4501. "We can also implement the function to accept a vector input from the beginning (requires more effort but might give better performance):"
  4502. ]
  4503. },
  4504. {
  4505. "cell_type": "code",
  4506. "execution_count": 217,
  4507. "metadata": {},
  4508. "outputs": [],
  4509. "source": [
  4510. "def Theta(x):\n",
  4511. " \"\"\"\n",
  4512. " Vector-aware implemenation of the Heaviside step function.\n",
  4513. " \"\"\"\n",
  4514. " return 1 * (x >= 0)"
  4515. ]
  4516. },
  4517. {
  4518. "cell_type": "code",
  4519. "execution_count": 219,
  4520. "metadata": {},
  4521. "outputs": [
  4522. {
  4523. "data": {
  4524. "text/plain": [
  4525. "array([0, 0, 0, 1, 1, 1, 1])"
  4526. ]
  4527. },
  4528. "execution_count": 219,
  4529. "metadata": {},
  4530. "output_type": "execute_result"
  4531. }
  4532. ],
  4533. "source": [
  4534. "Theta(np.array([-3,-2,-1,0,1,2,3]))"
  4535. ]
  4536. },
  4537. {
  4538. "cell_type": "code",
  4539. "execution_count": 221,
  4540. "metadata": {},
  4541. "outputs": [
  4542. {
  4543. "name": "stdout",
  4544. "output_type": "stream",
  4545. "text": [
  4546. "[False False False True True True True]\n"
  4547. ]
  4548. },
  4549. {
  4550. "data": {
  4551. "text/plain": [
  4552. "array([0, 0, 0, 1, 1, 1, 1])"
  4553. ]
  4554. },
  4555. "execution_count": 221,
  4556. "metadata": {},
  4557. "output_type": "execute_result"
  4558. }
  4559. ],
  4560. "source": [
  4561. "a = np.array([-3,-2,-1,0,1,2,3])\n",
  4562. "b = a>=0\n",
  4563. "print(b)\n",
  4564. "b*1"
  4565. ]
  4566. },
  4567. {
  4568. "cell_type": "code",
  4569. "execution_count": 222,
  4570. "metadata": {},
  4571. "outputs": [
  4572. {
  4573. "data": {
  4574. "text/plain": [
  4575. "(0, 1)"
  4576. ]
  4577. },
  4578. "execution_count": 222,
  4579. "metadata": {},
  4580. "output_type": "execute_result"
  4581. }
  4582. ],
  4583. "source": [
  4584. "# still works for scalars as well\n",
  4585. "Theta(-1.2), Theta(2.6)"
  4586. ]
  4587. },
  4588. {
  4589. "cell_type": "markdown",
  4590. "metadata": {},
  4591. "source": [
  4592. "## Using arrays in conditions"
  4593. ]
  4594. },
  4595. {
  4596. "cell_type": "markdown",
  4597. "metadata": {},
  4598. "source": [
  4599. "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`:"
  4600. ]
  4601. },
  4602. {
  4603. "cell_type": "code",
  4604. "execution_count": 223,
  4605. "metadata": {},
  4606. "outputs": [
  4607. {
  4608. "data": {
  4609. "text/plain": [
  4610. "array([[1, 2],\n",
  4611. " [3, 4]])"
  4612. ]
  4613. },
  4614. "execution_count": 223,
  4615. "metadata": {},
  4616. "output_type": "execute_result"
  4617. }
  4618. ],
  4619. "source": [
  4620. "M = np.array([[1, 2], [3, 4]])\n",
  4621. "M"
  4622. ]
  4623. },
  4624. {
  4625. "cell_type": "code",
  4626. "execution_count": 224,
  4627. "metadata": {},
  4628. "outputs": [
  4629. {
  4630. "data": {
  4631. "text/plain": [
  4632. "True"
  4633. ]
  4634. },
  4635. "execution_count": 224,
  4636. "metadata": {},
  4637. "output_type": "execute_result"
  4638. }
  4639. ],
  4640. "source": [
  4641. "(M > 2).any()"
  4642. ]
  4643. },
  4644. {
  4645. "cell_type": "code",
  4646. "execution_count": 225,
  4647. "metadata": {},
  4648. "outputs": [
  4649. {
  4650. "name": "stdout",
  4651. "output_type": "stream",
  4652. "text": [
  4653. "at least one element in M is larger than 2\n"
  4654. ]
  4655. }
  4656. ],
  4657. "source": [
  4658. "if (M > 2).any():\n",
  4659. " print(\"at least one element in M is larger than 2\")\n",
  4660. "else:\n",
  4661. " print(\"no element in M is larger than 2\")"
  4662. ]
  4663. },
  4664. {
  4665. "cell_type": "code",
  4666. "execution_count": 226,
  4667. "metadata": {},
  4668. "outputs": [
  4669. {
  4670. "name": "stdout",
  4671. "output_type": "stream",
  4672. "text": [
  4673. "all elements in M are not larger than 5\n"
  4674. ]
  4675. }
  4676. ],
  4677. "source": [
  4678. "if (M > 5).all():\n",
  4679. " print(\"all elements in M are larger than 5\")\n",
  4680. "else:\n",
  4681. " print(\"all elements in M are not larger than 5\")"
  4682. ]
  4683. },
  4684. {
  4685. "cell_type": "markdown",
  4686. "metadata": {},
  4687. "source": [
  4688. "## Type casting"
  4689. ]
  4690. },
  4691. {
  4692. "cell_type": "markdown",
  4693. "metadata": {},
  4694. "source": [
  4695. "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:"
  4696. ]
  4697. },
  4698. {
  4699. "cell_type": "code",
  4700. "execution_count": 227,
  4701. "metadata": {},
  4702. "outputs": [
  4703. {
  4704. "data": {
  4705. "text/plain": [
  4706. "dtype('int64')"
  4707. ]
  4708. },
  4709. "execution_count": 227,
  4710. "metadata": {},
  4711. "output_type": "execute_result"
  4712. }
  4713. ],
  4714. "source": [
  4715. "M.dtype"
  4716. ]
  4717. },
  4718. {
  4719. "cell_type": "code",
  4720. "execution_count": 228,
  4721. "metadata": {},
  4722. "outputs": [
  4723. {
  4724. "data": {
  4725. "text/plain": [
  4726. "array([[1., 2.],\n",
  4727. " [3., 4.]])"
  4728. ]
  4729. },
  4730. "execution_count": 228,
  4731. "metadata": {},
  4732. "output_type": "execute_result"
  4733. }
  4734. ],
  4735. "source": [
  4736. "M2 = M.astype(float)\n",
  4737. "\n",
  4738. "M2"
  4739. ]
  4740. },
  4741. {
  4742. "cell_type": "code",
  4743. "execution_count": 229,
  4744. "metadata": {},
  4745. "outputs": [
  4746. {
  4747. "data": {
  4748. "text/plain": [
  4749. "dtype('float64')"
  4750. ]
  4751. },
  4752. "execution_count": 229,
  4753. "metadata": {},
  4754. "output_type": "execute_result"
  4755. }
  4756. ],
  4757. "source": [
  4758. "M2.dtype"
  4759. ]
  4760. },
  4761. {
  4762. "cell_type": "code",
  4763. "execution_count": 230,
  4764. "metadata": {},
  4765. "outputs": [
  4766. {
  4767. "data": {
  4768. "text/plain": [
  4769. "array([[ True, True],\n",
  4770. " [ True, True]])"
  4771. ]
  4772. },
  4773. "execution_count": 230,
  4774. "metadata": {},
  4775. "output_type": "execute_result"
  4776. }
  4777. ],
  4778. "source": [
  4779. "M3 = M.astype(bool)\n",
  4780. "\n",
  4781. "M3"
  4782. ]
  4783. },
  4784. {
  4785. "cell_type": "markdown",
  4786. "metadata": {},
  4787. "source": [
  4788. "## Further reading"
  4789. ]
  4790. },
  4791. {
  4792. "cell_type": "markdown",
  4793. "metadata": {},
  4794. "source": [
  4795. "* http://numpy.scipy.org\n",
  4796. "* http://scipy.org/Tentative_NumPy_Tutorial\n",
  4797. "* http://scipy.org/NumPy_for_Matlab_Users - A Numpy guide for MATLAB users."
  4798. ]
  4799. },
  4800. {
  4801. "cell_type": "markdown",
  4802. "metadata": {},
  4803. "source": [
  4804. "## Versions"
  4805. ]
  4806. },
  4807. {
  4808. "cell_type": "code",
  4809. "execution_count": 178,
  4810. "metadata": {},
  4811. "outputs": [
  4812. {
  4813. "data": {
  4814. "application/json": {
  4815. "Software versions": [
  4816. {
  4817. "module": "Python",
  4818. "version": "2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]"
  4819. },
  4820. {
  4821. "module": "IPython",
  4822. "version": "3.2.1"
  4823. },
  4824. {
  4825. "module": "OS",
  4826. "version": "Darwin 14.1.0 x86_64 i386 64bit"
  4827. },
  4828. {
  4829. "module": "numpy",
  4830. "version": "1.9.2"
  4831. }
  4832. ]
  4833. },
  4834. "text/html": [
  4835. "<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>"
  4836. ],
  4837. "text/latex": [
  4838. "\\begin{tabular}{|l|l|}\\hline\n",
  4839. "{\\bf Software} & {\\bf Version} \\\\ \\hline\\hline\n",
  4840. "Python & 2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)] \\\\ \\hline\n",
  4841. "IPython & 3.2.1 \\\\ \\hline\n",
  4842. "OS & Darwin 14.1.0 x86\\_64 i386 64bit \\\\ \\hline\n",
  4843. "numpy & 1.9.2 \\\\ \\hline\n",
  4844. "\\hline \\multicolumn{2}{|l|}{Sat Aug 15 11:02:09 2015 JST} \\\\ \\hline\n",
  4845. "\\end{tabular}\n"
  4846. ],
  4847. "text/plain": [
  4848. "Software versions\n",
  4849. "Python 2.7.10 64bit [GCC 4.2.1 (Apple Inc. build 5577)]\n",
  4850. "IPython 3.2.1\n",
  4851. "OS Darwin 14.1.0 x86_64 i386 64bit\n",
  4852. "numpy 1.9.2\n",
  4853. "Sat Aug 15 11:02:09 2015 JST"
  4854. ]
  4855. },
  4856. "execution_count": 178,
  4857. "metadata": {},
  4858. "output_type": "execute_result"
  4859. }
  4860. ],
  4861. "source": [
  4862. "%reload_ext version_information\n",
  4863. "\n",
  4864. "%version_information numpy"
  4865. ]
  4866. }
  4867. ],
  4868. "metadata": {
  4869. "kernelspec": {
  4870. "display_name": "Python 3",
  4871. "language": "python",
  4872. "name": "python3"
  4873. },
  4874. "language_info": {
  4875. "codemirror_mode": {
  4876. "name": "ipython",
  4877. "version": 3
  4878. },
  4879. "file_extension": ".py",
  4880. "mimetype": "text/x-python",
  4881. "name": "python",
  4882. "nbconvert_exporter": "python",
  4883. "pygments_lexer": "ipython3",
  4884. "version": "3.6.8"
  4885. }
  4886. },
  4887. "nbformat": 4,
  4888. "nbformat_minor": 1
  4889. }

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