function_base.py 185 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733
  1. import collections.abc
  2. import functools
  3. import re
  4. import sys
  5. import warnings
  6. from .._utils import set_module
  7. import numpy as np
  8. import numpy.core.numeric as _nx
  9. from numpy.core import transpose
  10. from numpy.core.numeric import (
  11. ones, zeros_like, arange, concatenate, array, asarray, asanyarray, empty,
  12. ndarray, take, dot, where, intp, integer, isscalar, absolute
  13. )
  14. from numpy.core.umath import (
  15. pi, add, arctan2, frompyfunc, cos, less_equal, sqrt, sin,
  16. mod, exp, not_equal, subtract
  17. )
  18. from numpy.core.fromnumeric import (
  19. ravel, nonzero, partition, mean, any, sum
  20. )
  21. from numpy.core.numerictypes import typecodes
  22. from numpy.core import overrides
  23. from numpy.core.function_base import add_newdoc
  24. from numpy.lib.twodim_base import diag
  25. from numpy.core.multiarray import (
  26. _place, add_docstring, bincount, normalize_axis_index, _monotonicity,
  27. interp as compiled_interp, interp_complex as compiled_interp_complex
  28. )
  29. from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc
  30. import builtins
  31. # needed in this module for compatibility
  32. from numpy.lib.histograms import histogram, histogramdd # noqa: F401
  33. array_function_dispatch = functools.partial(
  34. overrides.array_function_dispatch, module='numpy')
  35. __all__ = [
  36. 'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
  37. 'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp', 'flip',
  38. 'rot90', 'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average',
  39. 'bincount', 'digitize', 'cov', 'corrcoef',
  40. 'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett',
  41. 'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc', 'add_docstring',
  42. 'meshgrid', 'delete', 'insert', 'append', 'interp', 'add_newdoc_ufunc',
  43. 'quantile'
  44. ]
  45. # _QuantileMethods is a dictionary listing all the supported methods to
  46. # compute quantile/percentile.
  47. #
  48. # Below virtual_index refer to the index of the element where the percentile
  49. # would be found in the sorted sample.
  50. # When the sample contains exactly the percentile wanted, the virtual_index is
  51. # an integer to the index of this element.
  52. # When the percentile wanted is in between two elements, the virtual_index
  53. # is made of a integer part (a.k.a 'i' or 'left') and a fractional part
  54. # (a.k.a 'g' or 'gamma')
  55. #
  56. # Each method in _QuantileMethods has two properties
  57. # get_virtual_index : Callable
  58. # The function used to compute the virtual_index.
  59. # fix_gamma : Callable
  60. # A function used for discret methods to force the index to a specific value.
  61. _QuantileMethods = dict(
  62. # --- HYNDMAN and FAN METHODS
  63. # Discrete methods
  64. inverted_cdf=dict(
  65. get_virtual_index=lambda n, quantiles: _inverted_cdf(n, quantiles),
  66. fix_gamma=lambda gamma, _: gamma, # should never be called
  67. ),
  68. averaged_inverted_cdf=dict(
  69. get_virtual_index=lambda n, quantiles: (n * quantiles) - 1,
  70. fix_gamma=lambda gamma, _: _get_gamma_mask(
  71. shape=gamma.shape,
  72. default_value=1.,
  73. conditioned_value=0.5,
  74. where=gamma == 0),
  75. ),
  76. closest_observation=dict(
  77. get_virtual_index=lambda n, quantiles: _closest_observation(n,
  78. quantiles),
  79. fix_gamma=lambda gamma, _: gamma, # should never be called
  80. ),
  81. # Continuous methods
  82. interpolated_inverted_cdf=dict(
  83. get_virtual_index=lambda n, quantiles:
  84. _compute_virtual_index(n, quantiles, 0, 1),
  85. fix_gamma=lambda gamma, _: gamma,
  86. ),
  87. hazen=dict(
  88. get_virtual_index=lambda n, quantiles:
  89. _compute_virtual_index(n, quantiles, 0.5, 0.5),
  90. fix_gamma=lambda gamma, _: gamma,
  91. ),
  92. weibull=dict(
  93. get_virtual_index=lambda n, quantiles:
  94. _compute_virtual_index(n, quantiles, 0, 0),
  95. fix_gamma=lambda gamma, _: gamma,
  96. ),
  97. # Default method.
  98. # To avoid some rounding issues, `(n-1) * quantiles` is preferred to
  99. # `_compute_virtual_index(n, quantiles, 1, 1)`.
  100. # They are mathematically equivalent.
  101. linear=dict(
  102. get_virtual_index=lambda n, quantiles: (n - 1) * quantiles,
  103. fix_gamma=lambda gamma, _: gamma,
  104. ),
  105. median_unbiased=dict(
  106. get_virtual_index=lambda n, quantiles:
  107. _compute_virtual_index(n, quantiles, 1 / 3.0, 1 / 3.0),
  108. fix_gamma=lambda gamma, _: gamma,
  109. ),
  110. normal_unbiased=dict(
  111. get_virtual_index=lambda n, quantiles:
  112. _compute_virtual_index(n, quantiles, 3 / 8.0, 3 / 8.0),
  113. fix_gamma=lambda gamma, _: gamma,
  114. ),
  115. # --- OTHER METHODS
  116. lower=dict(
  117. get_virtual_index=lambda n, quantiles: np.floor(
  118. (n - 1) * quantiles).astype(np.intp),
  119. fix_gamma=lambda gamma, _: gamma,
  120. # should never be called, index dtype is int
  121. ),
  122. higher=dict(
  123. get_virtual_index=lambda n, quantiles: np.ceil(
  124. (n - 1) * quantiles).astype(np.intp),
  125. fix_gamma=lambda gamma, _: gamma,
  126. # should never be called, index dtype is int
  127. ),
  128. midpoint=dict(
  129. get_virtual_index=lambda n, quantiles: 0.5 * (
  130. np.floor((n - 1) * quantiles)
  131. + np.ceil((n - 1) * quantiles)),
  132. fix_gamma=lambda gamma, index: _get_gamma_mask(
  133. shape=gamma.shape,
  134. default_value=0.5,
  135. conditioned_value=0.,
  136. where=index % 1 == 0),
  137. ),
  138. nearest=dict(
  139. get_virtual_index=lambda n, quantiles: np.around(
  140. (n - 1) * quantiles).astype(np.intp),
  141. fix_gamma=lambda gamma, _: gamma,
  142. # should never be called, index dtype is int
  143. ))
  144. def _rot90_dispatcher(m, k=None, axes=None):
  145. return (m,)
  146. @array_function_dispatch(_rot90_dispatcher)
  147. def rot90(m, k=1, axes=(0, 1)):
  148. """
  149. Rotate an array by 90 degrees in the plane specified by axes.
  150. Rotation direction is from the first towards the second axis.
  151. This means for a 2D array with the default `k` and `axes`, the
  152. rotation will be counterclockwise.
  153. Parameters
  154. ----------
  155. m : array_like
  156. Array of two or more dimensions.
  157. k : integer
  158. Number of times the array is rotated by 90 degrees.
  159. axes : (2,) array_like
  160. The array is rotated in the plane defined by the axes.
  161. Axes must be different.
  162. .. versionadded:: 1.12.0
  163. Returns
  164. -------
  165. y : ndarray
  166. A rotated view of `m`.
  167. See Also
  168. --------
  169. flip : Reverse the order of elements in an array along the given axis.
  170. fliplr : Flip an array horizontally.
  171. flipud : Flip an array vertically.
  172. Notes
  173. -----
  174. ``rot90(m, k=1, axes=(1,0))`` is the reverse of
  175. ``rot90(m, k=1, axes=(0,1))``
  176. ``rot90(m, k=1, axes=(1,0))`` is equivalent to
  177. ``rot90(m, k=-1, axes=(0,1))``
  178. Examples
  179. --------
  180. >>> m = np.array([[1,2],[3,4]], int)
  181. >>> m
  182. array([[1, 2],
  183. [3, 4]])
  184. >>> np.rot90(m)
  185. array([[2, 4],
  186. [1, 3]])
  187. >>> np.rot90(m, 2)
  188. array([[4, 3],
  189. [2, 1]])
  190. >>> m = np.arange(8).reshape((2,2,2))
  191. >>> np.rot90(m, 1, (1,2))
  192. array([[[1, 3],
  193. [0, 2]],
  194. [[5, 7],
  195. [4, 6]]])
  196. """
  197. axes = tuple(axes)
  198. if len(axes) != 2:
  199. raise ValueError("len(axes) must be 2.")
  200. m = asanyarray(m)
  201. if axes[0] == axes[1] or absolute(axes[0] - axes[1]) == m.ndim:
  202. raise ValueError("Axes must be different.")
  203. if (axes[0] >= m.ndim or axes[0] < -m.ndim
  204. or axes[1] >= m.ndim or axes[1] < -m.ndim):
  205. raise ValueError("Axes={} out of range for array of ndim={}."
  206. .format(axes, m.ndim))
  207. k %= 4
  208. if k == 0:
  209. return m[:]
  210. if k == 2:
  211. return flip(flip(m, axes[0]), axes[1])
  212. axes_list = arange(0, m.ndim)
  213. (axes_list[axes[0]], axes_list[axes[1]]) = (axes_list[axes[1]],
  214. axes_list[axes[0]])
  215. if k == 1:
  216. return transpose(flip(m, axes[1]), axes_list)
  217. else:
  218. # k == 3
  219. return flip(transpose(m, axes_list), axes[1])
  220. def _flip_dispatcher(m, axis=None):
  221. return (m,)
  222. @array_function_dispatch(_flip_dispatcher)
  223. def flip(m, axis=None):
  224. """
  225. Reverse the order of elements in an array along the given axis.
  226. The shape of the array is preserved, but the elements are reordered.
  227. .. versionadded:: 1.12.0
  228. Parameters
  229. ----------
  230. m : array_like
  231. Input array.
  232. axis : None or int or tuple of ints, optional
  233. Axis or axes along which to flip over. The default,
  234. axis=None, will flip over all of the axes of the input array.
  235. If axis is negative it counts from the last to the first axis.
  236. If axis is a tuple of ints, flipping is performed on all of the axes
  237. specified in the tuple.
  238. .. versionchanged:: 1.15.0
  239. None and tuples of axes are supported
  240. Returns
  241. -------
  242. out : array_like
  243. A view of `m` with the entries of axis reversed. Since a view is
  244. returned, this operation is done in constant time.
  245. See Also
  246. --------
  247. flipud : Flip an array vertically (axis=0).
  248. fliplr : Flip an array horizontally (axis=1).
  249. Notes
  250. -----
  251. flip(m, 0) is equivalent to flipud(m).
  252. flip(m, 1) is equivalent to fliplr(m).
  253. flip(m, n) corresponds to ``m[...,::-1,...]`` with ``::-1`` at position n.
  254. flip(m) corresponds to ``m[::-1,::-1,...,::-1]`` with ``::-1`` at all
  255. positions.
  256. flip(m, (0, 1)) corresponds to ``m[::-1,::-1,...]`` with ``::-1`` at
  257. position 0 and position 1.
  258. Examples
  259. --------
  260. >>> A = np.arange(8).reshape((2,2,2))
  261. >>> A
  262. array([[[0, 1],
  263. [2, 3]],
  264. [[4, 5],
  265. [6, 7]]])
  266. >>> np.flip(A, 0)
  267. array([[[4, 5],
  268. [6, 7]],
  269. [[0, 1],
  270. [2, 3]]])
  271. >>> np.flip(A, 1)
  272. array([[[2, 3],
  273. [0, 1]],
  274. [[6, 7],
  275. [4, 5]]])
  276. >>> np.flip(A)
  277. array([[[7, 6],
  278. [5, 4]],
  279. [[3, 2],
  280. [1, 0]]])
  281. >>> np.flip(A, (0, 2))
  282. array([[[5, 4],
  283. [7, 6]],
  284. [[1, 0],
  285. [3, 2]]])
  286. >>> A = np.random.randn(3,4,5)
  287. >>> np.all(np.flip(A,2) == A[:,:,::-1,...])
  288. True
  289. """
  290. if not hasattr(m, 'ndim'):
  291. m = asarray(m)
  292. if axis is None:
  293. indexer = (np.s_[::-1],) * m.ndim
  294. else:
  295. axis = _nx.normalize_axis_tuple(axis, m.ndim)
  296. indexer = [np.s_[:]] * m.ndim
  297. for ax in axis:
  298. indexer[ax] = np.s_[::-1]
  299. indexer = tuple(indexer)
  300. return m[indexer]
  301. @set_module('numpy')
  302. def iterable(y):
  303. """
  304. Check whether or not an object can be iterated over.
  305. Parameters
  306. ----------
  307. y : object
  308. Input object.
  309. Returns
  310. -------
  311. b : bool
  312. Return ``True`` if the object has an iterator method or is a
  313. sequence and ``False`` otherwise.
  314. Examples
  315. --------
  316. >>> np.iterable([1, 2, 3])
  317. True
  318. >>> np.iterable(2)
  319. False
  320. Notes
  321. -----
  322. In most cases, the results of ``np.iterable(obj)`` are consistent with
  323. ``isinstance(obj, collections.abc.Iterable)``. One notable exception is
  324. the treatment of 0-dimensional arrays::
  325. >>> from collections.abc import Iterable
  326. >>> a = np.array(1.0) # 0-dimensional numpy array
  327. >>> isinstance(a, Iterable)
  328. True
  329. >>> np.iterable(a)
  330. False
  331. """
  332. try:
  333. iter(y)
  334. except TypeError:
  335. return False
  336. return True
  337. def _average_dispatcher(a, axis=None, weights=None, returned=None, *,
  338. keepdims=None):
  339. return (a, weights)
  340. @array_function_dispatch(_average_dispatcher)
  341. def average(a, axis=None, weights=None, returned=False, *,
  342. keepdims=np._NoValue):
  343. """
  344. Compute the weighted average along the specified axis.
  345. Parameters
  346. ----------
  347. a : array_like
  348. Array containing data to be averaged. If `a` is not an array, a
  349. conversion is attempted.
  350. axis : None or int or tuple of ints, optional
  351. Axis or axes along which to average `a`. The default,
  352. axis=None, will average over all of the elements of the input array.
  353. If axis is negative it counts from the last to the first axis.
  354. .. versionadded:: 1.7.0
  355. If axis is a tuple of ints, averaging is performed on all of the axes
  356. specified in the tuple instead of a single axis or all the axes as
  357. before.
  358. weights : array_like, optional
  359. An array of weights associated with the values in `a`. Each value in
  360. `a` contributes to the average according to its associated weight.
  361. The weights array can either be 1-D (in which case its length must be
  362. the size of `a` along the given axis) or of the same shape as `a`.
  363. If `weights=None`, then all data in `a` are assumed to have a
  364. weight equal to one. The 1-D calculation is::
  365. avg = sum(a * weights) / sum(weights)
  366. The only constraint on `weights` is that `sum(weights)` must not be 0.
  367. returned : bool, optional
  368. Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`)
  369. is returned, otherwise only the average is returned.
  370. If `weights=None`, `sum_of_weights` is equivalent to the number of
  371. elements over which the average is taken.
  372. keepdims : bool, optional
  373. If this is set to True, the axes which are reduced are left
  374. in the result as dimensions with size one. With this option,
  375. the result will broadcast correctly against the original `a`.
  376. *Note:* `keepdims` will not work with instances of `numpy.matrix`
  377. or other classes whose methods do not support `keepdims`.
  378. .. versionadded:: 1.23.0
  379. Returns
  380. -------
  381. retval, [sum_of_weights] : array_type or double
  382. Return the average along the specified axis. When `returned` is `True`,
  383. return a tuple with the average as the first element and the sum
  384. of the weights as the second element. `sum_of_weights` is of the
  385. same type as `retval`. The result dtype follows a genereal pattern.
  386. If `weights` is None, the result dtype will be that of `a` , or ``float64``
  387. if `a` is integral. Otherwise, if `weights` is not None and `a` is non-
  388. integral, the result type will be the type of lowest precision capable of
  389. representing values of both `a` and `weights`. If `a` happens to be
  390. integral, the previous rules still applies but the result dtype will
  391. at least be ``float64``.
  392. Raises
  393. ------
  394. ZeroDivisionError
  395. When all weights along axis are zero. See `numpy.ma.average` for a
  396. version robust to this type of error.
  397. TypeError
  398. When the length of 1D `weights` is not the same as the shape of `a`
  399. along axis.
  400. See Also
  401. --------
  402. mean
  403. ma.average : average for masked arrays -- useful if your data contains
  404. "missing" values
  405. numpy.result_type : Returns the type that results from applying the
  406. numpy type promotion rules to the arguments.
  407. Examples
  408. --------
  409. >>> data = np.arange(1, 5)
  410. >>> data
  411. array([1, 2, 3, 4])
  412. >>> np.average(data)
  413. 2.5
  414. >>> np.average(np.arange(1, 11), weights=np.arange(10, 0, -1))
  415. 4.0
  416. >>> data = np.arange(6).reshape((3, 2))
  417. >>> data
  418. array([[0, 1],
  419. [2, 3],
  420. [4, 5]])
  421. >>> np.average(data, axis=1, weights=[1./4, 3./4])
  422. array([0.75, 2.75, 4.75])
  423. >>> np.average(data, weights=[1./4, 3./4])
  424. Traceback (most recent call last):
  425. ...
  426. TypeError: Axis must be specified when shapes of a and weights differ.
  427. >>> a = np.ones(5, dtype=np.float128)
  428. >>> w = np.ones(5, dtype=np.complex64)
  429. >>> avg = np.average(a, weights=w)
  430. >>> print(avg.dtype)
  431. complex256
  432. With ``keepdims=True``, the following result has shape (3, 1).
  433. >>> np.average(data, axis=1, keepdims=True)
  434. array([[0.5],
  435. [2.5],
  436. [4.5]])
  437. """
  438. a = np.asanyarray(a)
  439. if keepdims is np._NoValue:
  440. # Don't pass on the keepdims argument if one wasn't given.
  441. keepdims_kw = {}
  442. else:
  443. keepdims_kw = {'keepdims': keepdims}
  444. if weights is None:
  445. avg = a.mean(axis, **keepdims_kw)
  446. avg_as_array = np.asanyarray(avg)
  447. scl = avg_as_array.dtype.type(a.size/avg_as_array.size)
  448. else:
  449. wgt = np.asanyarray(weights)
  450. if issubclass(a.dtype.type, (np.integer, np.bool_)):
  451. result_dtype = np.result_type(a.dtype, wgt.dtype, 'f8')
  452. else:
  453. result_dtype = np.result_type(a.dtype, wgt.dtype)
  454. # Sanity checks
  455. if a.shape != wgt.shape:
  456. if axis is None:
  457. raise TypeError(
  458. "Axis must be specified when shapes of a and weights "
  459. "differ.")
  460. if wgt.ndim != 1:
  461. raise TypeError(
  462. "1D weights expected when shapes of a and weights differ.")
  463. if wgt.shape[0] != a.shape[axis]:
  464. raise ValueError(
  465. "Length of weights not compatible with specified axis.")
  466. # setup wgt to broadcast along axis
  467. wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape)
  468. wgt = wgt.swapaxes(-1, axis)
  469. scl = wgt.sum(axis=axis, dtype=result_dtype, **keepdims_kw)
  470. if np.any(scl == 0.0):
  471. raise ZeroDivisionError(
  472. "Weights sum to zero, can't be normalized")
  473. avg = avg_as_array = np.multiply(a, wgt,
  474. dtype=result_dtype).sum(axis, **keepdims_kw) / scl
  475. if returned:
  476. if scl.shape != avg_as_array.shape:
  477. scl = np.broadcast_to(scl, avg_as_array.shape).copy()
  478. return avg, scl
  479. else:
  480. return avg
  481. @set_module('numpy')
  482. def asarray_chkfinite(a, dtype=None, order=None):
  483. """Convert the input to an array, checking for NaNs or Infs.
  484. Parameters
  485. ----------
  486. a : array_like
  487. Input data, in any form that can be converted to an array. This
  488. includes lists, lists of tuples, tuples, tuples of tuples, tuples
  489. of lists and ndarrays. Success requires no NaNs or Infs.
  490. dtype : data-type, optional
  491. By default, the data-type is inferred from the input data.
  492. order : {'C', 'F', 'A', 'K'}, optional
  493. Memory layout. 'A' and 'K' depend on the order of input array a.
  494. 'C' row-major (C-style),
  495. 'F' column-major (Fortran-style) memory representation.
  496. 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
  497. 'K' (keep) preserve input order
  498. Defaults to 'C'.
  499. Returns
  500. -------
  501. out : ndarray
  502. Array interpretation of `a`. No copy is performed if the input
  503. is already an ndarray. If `a` is a subclass of ndarray, a base
  504. class ndarray is returned.
  505. Raises
  506. ------
  507. ValueError
  508. Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity).
  509. See Also
  510. --------
  511. asarray : Create and array.
  512. asanyarray : Similar function which passes through subclasses.
  513. ascontiguousarray : Convert input to a contiguous array.
  514. asfarray : Convert input to a floating point ndarray.
  515. asfortranarray : Convert input to an ndarray with column-major
  516. memory order.
  517. fromiter : Create an array from an iterator.
  518. fromfunction : Construct an array by executing a function on grid
  519. positions.
  520. Examples
  521. --------
  522. Convert a list into an array. If all elements are finite
  523. ``asarray_chkfinite`` is identical to ``asarray``.
  524. >>> a = [1, 2]
  525. >>> np.asarray_chkfinite(a, dtype=float)
  526. array([1., 2.])
  527. Raises ValueError if array_like contains Nans or Infs.
  528. >>> a = [1, 2, np.inf]
  529. >>> try:
  530. ... np.asarray_chkfinite(a)
  531. ... except ValueError:
  532. ... print('ValueError')
  533. ...
  534. ValueError
  535. """
  536. a = asarray(a, dtype=dtype, order=order)
  537. if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all():
  538. raise ValueError(
  539. "array must not contain infs or NaNs")
  540. return a
  541. def _piecewise_dispatcher(x, condlist, funclist, *args, **kw):
  542. yield x
  543. # support the undocumented behavior of allowing scalars
  544. if np.iterable(condlist):
  545. yield from condlist
  546. @array_function_dispatch(_piecewise_dispatcher)
  547. def piecewise(x, condlist, funclist, *args, **kw):
  548. """
  549. Evaluate a piecewise-defined function.
  550. Given a set of conditions and corresponding functions, evaluate each
  551. function on the input data wherever its condition is true.
  552. Parameters
  553. ----------
  554. x : ndarray or scalar
  555. The input domain.
  556. condlist : list of bool arrays or bool scalars
  557. Each boolean array corresponds to a function in `funclist`. Wherever
  558. `condlist[i]` is True, `funclist[i](x)` is used as the output value.
  559. Each boolean array in `condlist` selects a piece of `x`,
  560. and should therefore be of the same shape as `x`.
  561. The length of `condlist` must correspond to that of `funclist`.
  562. If one extra function is given, i.e. if
  563. ``len(funclist) == len(condlist) + 1``, then that extra function
  564. is the default value, used wherever all conditions are false.
  565. funclist : list of callables, f(x,*args,**kw), or scalars
  566. Each function is evaluated over `x` wherever its corresponding
  567. condition is True. It should take a 1d array as input and give an 1d
  568. array or a scalar value as output. If, instead of a callable,
  569. a scalar is provided then a constant function (``lambda x: scalar``) is
  570. assumed.
  571. args : tuple, optional
  572. Any further arguments given to `piecewise` are passed to the functions
  573. upon execution, i.e., if called ``piecewise(..., ..., 1, 'a')``, then
  574. each function is called as ``f(x, 1, 'a')``.
  575. kw : dict, optional
  576. Keyword arguments used in calling `piecewise` are passed to the
  577. functions upon execution, i.e., if called
  578. ``piecewise(..., ..., alpha=1)``, then each function is called as
  579. ``f(x, alpha=1)``.
  580. Returns
  581. -------
  582. out : ndarray
  583. The output is the same shape and type as x and is found by
  584. calling the functions in `funclist` on the appropriate portions of `x`,
  585. as defined by the boolean arrays in `condlist`. Portions not covered
  586. by any condition have a default value of 0.
  587. See Also
  588. --------
  589. choose, select, where
  590. Notes
  591. -----
  592. This is similar to choose or select, except that functions are
  593. evaluated on elements of `x` that satisfy the corresponding condition from
  594. `condlist`.
  595. The result is::
  596. |--
  597. |funclist[0](x[condlist[0]])
  598. out = |funclist[1](x[condlist[1]])
  599. |...
  600. |funclist[n2](x[condlist[n2]])
  601. |--
  602. Examples
  603. --------
  604. Define the sigma function, which is -1 for ``x < 0`` and +1 for ``x >= 0``.
  605. >>> x = np.linspace(-2.5, 2.5, 6)
  606. >>> np.piecewise(x, [x < 0, x >= 0], [-1, 1])
  607. array([-1., -1., -1., 1., 1., 1.])
  608. Define the absolute value, which is ``-x`` for ``x <0`` and ``x`` for
  609. ``x >= 0``.
  610. >>> np.piecewise(x, [x < 0, x >= 0], [lambda x: -x, lambda x: x])
  611. array([2.5, 1.5, 0.5, 0.5, 1.5, 2.5])
  612. Apply the same function to a scalar value.
  613. >>> y = -2
  614. >>> np.piecewise(y, [y < 0, y >= 0], [lambda x: -x, lambda x: x])
  615. array(2)
  616. """
  617. x = asanyarray(x)
  618. n2 = len(funclist)
  619. # undocumented: single condition is promoted to a list of one condition
  620. if isscalar(condlist) or (
  621. not isinstance(condlist[0], (list, ndarray)) and x.ndim != 0):
  622. condlist = [condlist]
  623. condlist = asarray(condlist, dtype=bool)
  624. n = len(condlist)
  625. if n == n2 - 1: # compute the "otherwise" condition.
  626. condelse = ~np.any(condlist, axis=0, keepdims=True)
  627. condlist = np.concatenate([condlist, condelse], axis=0)
  628. n += 1
  629. elif n != n2:
  630. raise ValueError(
  631. "with {} condition(s), either {} or {} functions are expected"
  632. .format(n, n, n+1)
  633. )
  634. y = zeros_like(x)
  635. for cond, func in zip(condlist, funclist):
  636. if not isinstance(func, collections.abc.Callable):
  637. y[cond] = func
  638. else:
  639. vals = x[cond]
  640. if vals.size > 0:
  641. y[cond] = func(vals, *args, **kw)
  642. return y
  643. def _select_dispatcher(condlist, choicelist, default=None):
  644. yield from condlist
  645. yield from choicelist
  646. @array_function_dispatch(_select_dispatcher)
  647. def select(condlist, choicelist, default=0):
  648. """
  649. Return an array drawn from elements in choicelist, depending on conditions.
  650. Parameters
  651. ----------
  652. condlist : list of bool ndarrays
  653. The list of conditions which determine from which array in `choicelist`
  654. the output elements are taken. When multiple conditions are satisfied,
  655. the first one encountered in `condlist` is used.
  656. choicelist : list of ndarrays
  657. The list of arrays from which the output elements are taken. It has
  658. to be of the same length as `condlist`.
  659. default : scalar, optional
  660. The element inserted in `output` when all conditions evaluate to False.
  661. Returns
  662. -------
  663. output : ndarray
  664. The output at position m is the m-th element of the array in
  665. `choicelist` where the m-th element of the corresponding array in
  666. `condlist` is True.
  667. See Also
  668. --------
  669. where : Return elements from one of two arrays depending on condition.
  670. take, choose, compress, diag, diagonal
  671. Examples
  672. --------
  673. >>> x = np.arange(6)
  674. >>> condlist = [x<3, x>3]
  675. >>> choicelist = [x, x**2]
  676. >>> np.select(condlist, choicelist, 42)
  677. array([ 0, 1, 2, 42, 16, 25])
  678. >>> condlist = [x<=4, x>3]
  679. >>> choicelist = [x, x**2]
  680. >>> np.select(condlist, choicelist, 55)
  681. array([ 0, 1, 2, 3, 4, 25])
  682. """
  683. # Check the size of condlist and choicelist are the same, or abort.
  684. if len(condlist) != len(choicelist):
  685. raise ValueError(
  686. 'list of cases must be same length as list of conditions')
  687. # Now that the dtype is known, handle the deprecated select([], []) case
  688. if len(condlist) == 0:
  689. raise ValueError("select with an empty condition list is not possible")
  690. choicelist = [np.asarray(choice) for choice in choicelist]
  691. try:
  692. intermediate_dtype = np.result_type(*choicelist)
  693. except TypeError as e:
  694. msg = f'Choicelist elements do not have a common dtype: {e}'
  695. raise TypeError(msg) from None
  696. default_array = np.asarray(default)
  697. choicelist.append(default_array)
  698. # need to get the result type before broadcasting for correct scalar
  699. # behaviour
  700. try:
  701. dtype = np.result_type(intermediate_dtype, default_array)
  702. except TypeError as e:
  703. msg = f'Choicelists and default value do not have a common dtype: {e}'
  704. raise TypeError(msg) from None
  705. # Convert conditions to arrays and broadcast conditions and choices
  706. # as the shape is needed for the result. Doing it separately optimizes
  707. # for example when all choices are scalars.
  708. condlist = np.broadcast_arrays(*condlist)
  709. choicelist = np.broadcast_arrays(*choicelist)
  710. # If cond array is not an ndarray in boolean format or scalar bool, abort.
  711. for i, cond in enumerate(condlist):
  712. if cond.dtype.type is not np.bool_:
  713. raise TypeError(
  714. 'invalid entry {} in condlist: should be boolean ndarray'.format(i))
  715. if choicelist[0].ndim == 0:
  716. # This may be common, so avoid the call.
  717. result_shape = condlist[0].shape
  718. else:
  719. result_shape = np.broadcast_arrays(condlist[0], choicelist[0])[0].shape
  720. result = np.full(result_shape, choicelist[-1], dtype)
  721. # Use np.copyto to burn each choicelist array onto result, using the
  722. # corresponding condlist as a boolean mask. This is done in reverse
  723. # order since the first choice should take precedence.
  724. choicelist = choicelist[-2::-1]
  725. condlist = condlist[::-1]
  726. for choice, cond in zip(choicelist, condlist):
  727. np.copyto(result, choice, where=cond)
  728. return result
  729. def _copy_dispatcher(a, order=None, subok=None):
  730. return (a,)
  731. @array_function_dispatch(_copy_dispatcher)
  732. def copy(a, order='K', subok=False):
  733. """
  734. Return an array copy of the given object.
  735. Parameters
  736. ----------
  737. a : array_like
  738. Input data.
  739. order : {'C', 'F', 'A', 'K'}, optional
  740. Controls the memory layout of the copy. 'C' means C-order,
  741. 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
  742. 'C' otherwise. 'K' means match the layout of `a` as closely
  743. as possible. (Note that this function and :meth:`ndarray.copy` are very
  744. similar, but have different default values for their order=
  745. arguments.)
  746. subok : bool, optional
  747. If True, then sub-classes will be passed-through, otherwise the
  748. returned array will be forced to be a base-class array (defaults to False).
  749. .. versionadded:: 1.19.0
  750. Returns
  751. -------
  752. arr : ndarray
  753. Array interpretation of `a`.
  754. See Also
  755. --------
  756. ndarray.copy : Preferred method for creating an array copy
  757. Notes
  758. -----
  759. This is equivalent to:
  760. >>> np.array(a, copy=True) #doctest: +SKIP
  761. Examples
  762. --------
  763. Create an array x, with a reference y and a copy z:
  764. >>> x = np.array([1, 2, 3])
  765. >>> y = x
  766. >>> z = np.copy(x)
  767. Note that, when we modify x, y changes, but not z:
  768. >>> x[0] = 10
  769. >>> x[0] == y[0]
  770. True
  771. >>> x[0] == z[0]
  772. False
  773. Note that, np.copy clears previously set WRITEABLE=False flag.
  774. >>> a = np.array([1, 2, 3])
  775. >>> a.flags["WRITEABLE"] = False
  776. >>> b = np.copy(a)
  777. >>> b.flags["WRITEABLE"]
  778. True
  779. >>> b[0] = 3
  780. >>> b
  781. array([3, 2, 3])
  782. Note that np.copy is a shallow copy and will not copy object
  783. elements within arrays. This is mainly important for arrays
  784. containing Python objects. The new array will contain the
  785. same object which may lead to surprises if that object can
  786. be modified (is mutable):
  787. >>> a = np.array([1, 'm', [2, 3, 4]], dtype=object)
  788. >>> b = np.copy(a)
  789. >>> b[2][0] = 10
  790. >>> a
  791. array([1, 'm', list([10, 3, 4])], dtype=object)
  792. To ensure all elements within an ``object`` array are copied,
  793. use `copy.deepcopy`:
  794. >>> import copy
  795. >>> a = np.array([1, 'm', [2, 3, 4]], dtype=object)
  796. >>> c = copy.deepcopy(a)
  797. >>> c[2][0] = 10
  798. >>> c
  799. array([1, 'm', list([10, 3, 4])], dtype=object)
  800. >>> a
  801. array([1, 'm', list([2, 3, 4])], dtype=object)
  802. """
  803. return array(a, order=order, subok=subok, copy=True)
  804. # Basic operations
  805. def _gradient_dispatcher(f, *varargs, axis=None, edge_order=None):
  806. yield f
  807. yield from varargs
  808. @array_function_dispatch(_gradient_dispatcher)
  809. def gradient(f, *varargs, axis=None, edge_order=1):
  810. """
  811. Return the gradient of an N-dimensional array.
  812. The gradient is computed using second order accurate central differences
  813. in the interior points and either first or second order accurate one-sides
  814. (forward or backwards) differences at the boundaries.
  815. The returned gradient hence has the same shape as the input array.
  816. Parameters
  817. ----------
  818. f : array_like
  819. An N-dimensional array containing samples of a scalar function.
  820. varargs : list of scalar or array, optional
  821. Spacing between f values. Default unitary spacing for all dimensions.
  822. Spacing can be specified using:
  823. 1. single scalar to specify a sample distance for all dimensions.
  824. 2. N scalars to specify a constant sample distance for each dimension.
  825. i.e. `dx`, `dy`, `dz`, ...
  826. 3. N arrays to specify the coordinates of the values along each
  827. dimension of F. The length of the array must match the size of
  828. the corresponding dimension
  829. 4. Any combination of N scalars/arrays with the meaning of 2. and 3.
  830. If `axis` is given, the number of varargs must equal the number of axes.
  831. Default: 1.
  832. edge_order : {1, 2}, optional
  833. Gradient is calculated using N-th order accurate differences
  834. at the boundaries. Default: 1.
  835. .. versionadded:: 1.9.1
  836. axis : None or int or tuple of ints, optional
  837. Gradient is calculated only along the given axis or axes
  838. The default (axis = None) is to calculate the gradient for all the axes
  839. of the input array. axis may be negative, in which case it counts from
  840. the last to the first axis.
  841. .. versionadded:: 1.11.0
  842. Returns
  843. -------
  844. gradient : ndarray or list of ndarray
  845. A list of ndarrays (or a single ndarray if there is only one dimension)
  846. corresponding to the derivatives of f with respect to each dimension.
  847. Each derivative has the same shape as f.
  848. Examples
  849. --------
  850. >>> f = np.array([1, 2, 4, 7, 11, 16], dtype=float)
  851. >>> np.gradient(f)
  852. array([1. , 1.5, 2.5, 3.5, 4.5, 5. ])
  853. >>> np.gradient(f, 2)
  854. array([0.5 , 0.75, 1.25, 1.75, 2.25, 2.5 ])
  855. Spacing can be also specified with an array that represents the coordinates
  856. of the values F along the dimensions.
  857. For instance a uniform spacing:
  858. >>> x = np.arange(f.size)
  859. >>> np.gradient(f, x)
  860. array([1. , 1.5, 2.5, 3.5, 4.5, 5. ])
  861. Or a non uniform one:
  862. >>> x = np.array([0., 1., 1.5, 3.5, 4., 6.], dtype=float)
  863. >>> np.gradient(f, x)
  864. array([1. , 3. , 3.5, 6.7, 6.9, 2.5])
  865. For two dimensional arrays, the return will be two arrays ordered by
  866. axis. In this example the first array stands for the gradient in
  867. rows and the second one in columns direction:
  868. >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float))
  869. [array([[ 2., 2., -1.],
  870. [ 2., 2., -1.]]), array([[1. , 2.5, 4. ],
  871. [1. , 1. , 1. ]])]
  872. In this example the spacing is also specified:
  873. uniform for axis=0 and non uniform for axis=1
  874. >>> dx = 2.
  875. >>> y = [1., 1.5, 3.5]
  876. >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float), dx, y)
  877. [array([[ 1. , 1. , -0.5],
  878. [ 1. , 1. , -0.5]]), array([[2. , 2. , 2. ],
  879. [2. , 1.7, 0.5]])]
  880. It is possible to specify how boundaries are treated using `edge_order`
  881. >>> x = np.array([0, 1, 2, 3, 4])
  882. >>> f = x**2
  883. >>> np.gradient(f, edge_order=1)
  884. array([1., 2., 4., 6., 7.])
  885. >>> np.gradient(f, edge_order=2)
  886. array([0., 2., 4., 6., 8.])
  887. The `axis` keyword can be used to specify a subset of axes of which the
  888. gradient is calculated
  889. >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float), axis=0)
  890. array([[ 2., 2., -1.],
  891. [ 2., 2., -1.]])
  892. Notes
  893. -----
  894. Assuming that :math:`f\\in C^{3}` (i.e., :math:`f` has at least 3 continuous
  895. derivatives) and let :math:`h_{*}` be a non-homogeneous stepsize, we
  896. minimize the "consistency error" :math:`\\eta_{i}` between the true gradient
  897. and its estimate from a linear combination of the neighboring grid-points:
  898. .. math::
  899. \\eta_{i} = f_{i}^{\\left(1\\right)} -
  900. \\left[ \\alpha f\\left(x_{i}\\right) +
  901. \\beta f\\left(x_{i} + h_{d}\\right) +
  902. \\gamma f\\left(x_{i}-h_{s}\\right)
  903. \\right]
  904. By substituting :math:`f(x_{i} + h_{d})` and :math:`f(x_{i} - h_{s})`
  905. with their Taylor series expansion, this translates into solving
  906. the following the linear system:
  907. .. math::
  908. \\left\\{
  909. \\begin{array}{r}
  910. \\alpha+\\beta+\\gamma=0 \\\\
  911. \\beta h_{d}-\\gamma h_{s}=1 \\\\
  912. \\beta h_{d}^{2}+\\gamma h_{s}^{2}=0
  913. \\end{array}
  914. \\right.
  915. The resulting approximation of :math:`f_{i}^{(1)}` is the following:
  916. .. math::
  917. \\hat f_{i}^{(1)} =
  918. \\frac{
  919. h_{s}^{2}f\\left(x_{i} + h_{d}\\right)
  920. + \\left(h_{d}^{2} - h_{s}^{2}\\right)f\\left(x_{i}\\right)
  921. - h_{d}^{2}f\\left(x_{i}-h_{s}\\right)}
  922. { h_{s}h_{d}\\left(h_{d} + h_{s}\\right)}
  923. + \\mathcal{O}\\left(\\frac{h_{d}h_{s}^{2}
  924. + h_{s}h_{d}^{2}}{h_{d}
  925. + h_{s}}\\right)
  926. It is worth noting that if :math:`h_{s}=h_{d}`
  927. (i.e., data are evenly spaced)
  928. we find the standard second order approximation:
  929. .. math::
  930. \\hat f_{i}^{(1)}=
  931. \\frac{f\\left(x_{i+1}\\right) - f\\left(x_{i-1}\\right)}{2h}
  932. + \\mathcal{O}\\left(h^{2}\\right)
  933. With a similar procedure the forward/backward approximations used for
  934. boundaries can be derived.
  935. References
  936. ----------
  937. .. [1] Quarteroni A., Sacco R., Saleri F. (2007) Numerical Mathematics
  938. (Texts in Applied Mathematics). New York: Springer.
  939. .. [2] Durran D. R. (1999) Numerical Methods for Wave Equations
  940. in Geophysical Fluid Dynamics. New York: Springer.
  941. .. [3] Fornberg B. (1988) Generation of Finite Difference Formulas on
  942. Arbitrarily Spaced Grids,
  943. Mathematics of Computation 51, no. 184 : 699-706.
  944. `PDF <http://www.ams.org/journals/mcom/1988-51-184/
  945. S0025-5718-1988-0935077-0/S0025-5718-1988-0935077-0.pdf>`_.
  946. """
  947. f = np.asanyarray(f)
  948. N = f.ndim # number of dimensions
  949. if axis is None:
  950. axes = tuple(range(N))
  951. else:
  952. axes = _nx.normalize_axis_tuple(axis, N)
  953. len_axes = len(axes)
  954. n = len(varargs)
  955. if n == 0:
  956. # no spacing argument - use 1 in all axes
  957. dx = [1.0] * len_axes
  958. elif n == 1 and np.ndim(varargs[0]) == 0:
  959. # single scalar for all axes
  960. dx = varargs * len_axes
  961. elif n == len_axes:
  962. # scalar or 1d array for each axis
  963. dx = list(varargs)
  964. for i, distances in enumerate(dx):
  965. distances = np.asanyarray(distances)
  966. if distances.ndim == 0:
  967. continue
  968. elif distances.ndim != 1:
  969. raise ValueError("distances must be either scalars or 1d")
  970. if len(distances) != f.shape[axes[i]]:
  971. raise ValueError("when 1d, distances must match "
  972. "the length of the corresponding dimension")
  973. if np.issubdtype(distances.dtype, np.integer):
  974. # Convert numpy integer types to float64 to avoid modular
  975. # arithmetic in np.diff(distances).
  976. distances = distances.astype(np.float64)
  977. diffx = np.diff(distances)
  978. # if distances are constant reduce to the scalar case
  979. # since it brings a consistent speedup
  980. if (diffx == diffx[0]).all():
  981. diffx = diffx[0]
  982. dx[i] = diffx
  983. else:
  984. raise TypeError("invalid number of arguments")
  985. if edge_order > 2:
  986. raise ValueError("'edge_order' greater than 2 not supported")
  987. # use central differences on interior and one-sided differences on the
  988. # endpoints. This preserves second order-accuracy over the full domain.
  989. outvals = []
  990. # create slice objects --- initially all are [:, :, ..., :]
  991. slice1 = [slice(None)]*N
  992. slice2 = [slice(None)]*N
  993. slice3 = [slice(None)]*N
  994. slice4 = [slice(None)]*N
  995. otype = f.dtype
  996. if otype.type is np.datetime64:
  997. # the timedelta dtype with the same unit information
  998. otype = np.dtype(otype.name.replace('datetime', 'timedelta'))
  999. # view as timedelta to allow addition
  1000. f = f.view(otype)
  1001. elif otype.type is np.timedelta64:
  1002. pass
  1003. elif np.issubdtype(otype, np.inexact):
  1004. pass
  1005. else:
  1006. # All other types convert to floating point.
  1007. # First check if f is a numpy integer type; if so, convert f to float64
  1008. # to avoid modular arithmetic when computing the changes in f.
  1009. if np.issubdtype(otype, np.integer):
  1010. f = f.astype(np.float64)
  1011. otype = np.float64
  1012. for axis, ax_dx in zip(axes, dx):
  1013. if f.shape[axis] < edge_order + 1:
  1014. raise ValueError(
  1015. "Shape of array too small to calculate a numerical gradient, "
  1016. "at least (edge_order + 1) elements are required.")
  1017. # result allocation
  1018. out = np.empty_like(f, dtype=otype)
  1019. # spacing for the current axis
  1020. uniform_spacing = np.ndim(ax_dx) == 0
  1021. # Numerical differentiation: 2nd order interior
  1022. slice1[axis] = slice(1, -1)
  1023. slice2[axis] = slice(None, -2)
  1024. slice3[axis] = slice(1, -1)
  1025. slice4[axis] = slice(2, None)
  1026. if uniform_spacing:
  1027. out[tuple(slice1)] = (f[tuple(slice4)] - f[tuple(slice2)]) / (2. * ax_dx)
  1028. else:
  1029. dx1 = ax_dx[0:-1]
  1030. dx2 = ax_dx[1:]
  1031. a = -(dx2)/(dx1 * (dx1 + dx2))
  1032. b = (dx2 - dx1) / (dx1 * dx2)
  1033. c = dx1 / (dx2 * (dx1 + dx2))
  1034. # fix the shape for broadcasting
  1035. shape = np.ones(N, dtype=int)
  1036. shape[axis] = -1
  1037. a.shape = b.shape = c.shape = shape
  1038. # 1D equivalent -- out[1:-1] = a * f[:-2] + b * f[1:-1] + c * f[2:]
  1039. out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)]
  1040. # Numerical differentiation: 1st order edges
  1041. if edge_order == 1:
  1042. slice1[axis] = 0
  1043. slice2[axis] = 1
  1044. slice3[axis] = 0
  1045. dx_0 = ax_dx if uniform_spacing else ax_dx[0]
  1046. # 1D equivalent -- out[0] = (f[1] - f[0]) / (x[1] - x[0])
  1047. out[tuple(slice1)] = (f[tuple(slice2)] - f[tuple(slice3)]) / dx_0
  1048. slice1[axis] = -1
  1049. slice2[axis] = -1
  1050. slice3[axis] = -2
  1051. dx_n = ax_dx if uniform_spacing else ax_dx[-1]
  1052. # 1D equivalent -- out[-1] = (f[-1] - f[-2]) / (x[-1] - x[-2])
  1053. out[tuple(slice1)] = (f[tuple(slice2)] - f[tuple(slice3)]) / dx_n
  1054. # Numerical differentiation: 2nd order edges
  1055. else:
  1056. slice1[axis] = 0
  1057. slice2[axis] = 0
  1058. slice3[axis] = 1
  1059. slice4[axis] = 2
  1060. if uniform_spacing:
  1061. a = -1.5 / ax_dx
  1062. b = 2. / ax_dx
  1063. c = -0.5 / ax_dx
  1064. else:
  1065. dx1 = ax_dx[0]
  1066. dx2 = ax_dx[1]
  1067. a = -(2. * dx1 + dx2)/(dx1 * (dx1 + dx2))
  1068. b = (dx1 + dx2) / (dx1 * dx2)
  1069. c = - dx1 / (dx2 * (dx1 + dx2))
  1070. # 1D equivalent -- out[0] = a * f[0] + b * f[1] + c * f[2]
  1071. out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)]
  1072. slice1[axis] = -1
  1073. slice2[axis] = -3
  1074. slice3[axis] = -2
  1075. slice4[axis] = -1
  1076. if uniform_spacing:
  1077. a = 0.5 / ax_dx
  1078. b = -2. / ax_dx
  1079. c = 1.5 / ax_dx
  1080. else:
  1081. dx1 = ax_dx[-2]
  1082. dx2 = ax_dx[-1]
  1083. a = (dx2) / (dx1 * (dx1 + dx2))
  1084. b = - (dx2 + dx1) / (dx1 * dx2)
  1085. c = (2. * dx2 + dx1) / (dx2 * (dx1 + dx2))
  1086. # 1D equivalent -- out[-1] = a * f[-3] + b * f[-2] + c * f[-1]
  1087. out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)]
  1088. outvals.append(out)
  1089. # reset the slice object in this dimension to ":"
  1090. slice1[axis] = slice(None)
  1091. slice2[axis] = slice(None)
  1092. slice3[axis] = slice(None)
  1093. slice4[axis] = slice(None)
  1094. if len_axes == 1:
  1095. return outvals[0]
  1096. elif np._using_numpy2_behavior():
  1097. return tuple(outvals)
  1098. else:
  1099. return outvals
  1100. def _diff_dispatcher(a, n=None, axis=None, prepend=None, append=None):
  1101. return (a, prepend, append)
  1102. @array_function_dispatch(_diff_dispatcher)
  1103. def diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue):
  1104. """
  1105. Calculate the n-th discrete difference along the given axis.
  1106. The first difference is given by ``out[i] = a[i+1] - a[i]`` along
  1107. the given axis, higher differences are calculated by using `diff`
  1108. recursively.
  1109. Parameters
  1110. ----------
  1111. a : array_like
  1112. Input array
  1113. n : int, optional
  1114. The number of times values are differenced. If zero, the input
  1115. is returned as-is.
  1116. axis : int, optional
  1117. The axis along which the difference is taken, default is the
  1118. last axis.
  1119. prepend, append : array_like, optional
  1120. Values to prepend or append to `a` along axis prior to
  1121. performing the difference. Scalar values are expanded to
  1122. arrays with length 1 in the direction of axis and the shape
  1123. of the input array in along all other axes. Otherwise the
  1124. dimension and shape must match `a` except along axis.
  1125. .. versionadded:: 1.16.0
  1126. Returns
  1127. -------
  1128. diff : ndarray
  1129. The n-th differences. The shape of the output is the same as `a`
  1130. except along `axis` where the dimension is smaller by `n`. The
  1131. type of the output is the same as the type of the difference
  1132. between any two elements of `a`. This is the same as the type of
  1133. `a` in most cases. A notable exception is `datetime64`, which
  1134. results in a `timedelta64` output array.
  1135. See Also
  1136. --------
  1137. gradient, ediff1d, cumsum
  1138. Notes
  1139. -----
  1140. Type is preserved for boolean arrays, so the result will contain
  1141. `False` when consecutive elements are the same and `True` when they
  1142. differ.
  1143. For unsigned integer arrays, the results will also be unsigned. This
  1144. should not be surprising, as the result is consistent with
  1145. calculating the difference directly:
  1146. >>> u8_arr = np.array([1, 0], dtype=np.uint8)
  1147. >>> np.diff(u8_arr)
  1148. array([255], dtype=uint8)
  1149. >>> u8_arr[1,...] - u8_arr[0,...]
  1150. 255
  1151. If this is not desirable, then the array should be cast to a larger
  1152. integer type first:
  1153. >>> i16_arr = u8_arr.astype(np.int16)
  1154. >>> np.diff(i16_arr)
  1155. array([-1], dtype=int16)
  1156. Examples
  1157. --------
  1158. >>> x = np.array([1, 2, 4, 7, 0])
  1159. >>> np.diff(x)
  1160. array([ 1, 2, 3, -7])
  1161. >>> np.diff(x, n=2)
  1162. array([ 1, 1, -10])
  1163. >>> x = np.array([[1, 3, 6, 10], [0, 5, 6, 8]])
  1164. >>> np.diff(x)
  1165. array([[2, 3, 4],
  1166. [5, 1, 2]])
  1167. >>> np.diff(x, axis=0)
  1168. array([[-1, 2, 0, -2]])
  1169. >>> x = np.arange('1066-10-13', '1066-10-16', dtype=np.datetime64)
  1170. >>> np.diff(x)
  1171. array([1, 1], dtype='timedelta64[D]')
  1172. """
  1173. if n == 0:
  1174. return a
  1175. if n < 0:
  1176. raise ValueError(
  1177. "order must be non-negative but got " + repr(n))
  1178. a = asanyarray(a)
  1179. nd = a.ndim
  1180. if nd == 0:
  1181. raise ValueError("diff requires input that is at least one dimensional")
  1182. axis = normalize_axis_index(axis, nd)
  1183. combined = []
  1184. if prepend is not np._NoValue:
  1185. prepend = np.asanyarray(prepend)
  1186. if prepend.ndim == 0:
  1187. shape = list(a.shape)
  1188. shape[axis] = 1
  1189. prepend = np.broadcast_to(prepend, tuple(shape))
  1190. combined.append(prepend)
  1191. combined.append(a)
  1192. if append is not np._NoValue:
  1193. append = np.asanyarray(append)
  1194. if append.ndim == 0:
  1195. shape = list(a.shape)
  1196. shape[axis] = 1
  1197. append = np.broadcast_to(append, tuple(shape))
  1198. combined.append(append)
  1199. if len(combined) > 1:
  1200. a = np.concatenate(combined, axis)
  1201. slice1 = [slice(None)] * nd
  1202. slice2 = [slice(None)] * nd
  1203. slice1[axis] = slice(1, None)
  1204. slice2[axis] = slice(None, -1)
  1205. slice1 = tuple(slice1)
  1206. slice2 = tuple(slice2)
  1207. op = not_equal if a.dtype == np.bool_ else subtract
  1208. for _ in range(n):
  1209. a = op(a[slice1], a[slice2])
  1210. return a
  1211. def _interp_dispatcher(x, xp, fp, left=None, right=None, period=None):
  1212. return (x, xp, fp)
  1213. @array_function_dispatch(_interp_dispatcher)
  1214. def interp(x, xp, fp, left=None, right=None, period=None):
  1215. """
  1216. One-dimensional linear interpolation for monotonically increasing sample points.
  1217. Returns the one-dimensional piecewise linear interpolant to a function
  1218. with given discrete data points (`xp`, `fp`), evaluated at `x`.
  1219. Parameters
  1220. ----------
  1221. x : array_like
  1222. The x-coordinates at which to evaluate the interpolated values.
  1223. xp : 1-D sequence of floats
  1224. The x-coordinates of the data points, must be increasing if argument
  1225. `period` is not specified. Otherwise, `xp` is internally sorted after
  1226. normalizing the periodic boundaries with ``xp = xp % period``.
  1227. fp : 1-D sequence of float or complex
  1228. The y-coordinates of the data points, same length as `xp`.
  1229. left : optional float or complex corresponding to fp
  1230. Value to return for `x < xp[0]`, default is `fp[0]`.
  1231. right : optional float or complex corresponding to fp
  1232. Value to return for `x > xp[-1]`, default is `fp[-1]`.
  1233. period : None or float, optional
  1234. A period for the x-coordinates. This parameter allows the proper
  1235. interpolation of angular x-coordinates. Parameters `left` and `right`
  1236. are ignored if `period` is specified.
  1237. .. versionadded:: 1.10.0
  1238. Returns
  1239. -------
  1240. y : float or complex (corresponding to fp) or ndarray
  1241. The interpolated values, same shape as `x`.
  1242. Raises
  1243. ------
  1244. ValueError
  1245. If `xp` and `fp` have different length
  1246. If `xp` or `fp` are not 1-D sequences
  1247. If `period == 0`
  1248. See Also
  1249. --------
  1250. scipy.interpolate
  1251. Warnings
  1252. --------
  1253. The x-coordinate sequence is expected to be increasing, but this is not
  1254. explicitly enforced. However, if the sequence `xp` is non-increasing,
  1255. interpolation results are meaningless.
  1256. Note that, since NaN is unsortable, `xp` also cannot contain NaNs.
  1257. A simple check for `xp` being strictly increasing is::
  1258. np.all(np.diff(xp) > 0)
  1259. Examples
  1260. --------
  1261. >>> xp = [1, 2, 3]
  1262. >>> fp = [3, 2, 0]
  1263. >>> np.interp(2.5, xp, fp)
  1264. 1.0
  1265. >>> np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp)
  1266. array([3. , 3. , 2.5 , 0.56, 0. ])
  1267. >>> UNDEF = -99.0
  1268. >>> np.interp(3.14, xp, fp, right=UNDEF)
  1269. -99.0
  1270. Plot an interpolant to the sine function:
  1271. >>> x = np.linspace(0, 2*np.pi, 10)
  1272. >>> y = np.sin(x)
  1273. >>> xvals = np.linspace(0, 2*np.pi, 50)
  1274. >>> yinterp = np.interp(xvals, x, y)
  1275. >>> import matplotlib.pyplot as plt
  1276. >>> plt.plot(x, y, 'o')
  1277. [<matplotlib.lines.Line2D object at 0x...>]
  1278. >>> plt.plot(xvals, yinterp, '-x')
  1279. [<matplotlib.lines.Line2D object at 0x...>]
  1280. >>> plt.show()
  1281. Interpolation with periodic x-coordinates:
  1282. >>> x = [-180, -170, -185, 185, -10, -5, 0, 365]
  1283. >>> xp = [190, -190, 350, -350]
  1284. >>> fp = [5, 10, 3, 4]
  1285. >>> np.interp(x, xp, fp, period=360)
  1286. array([7.5 , 5. , 8.75, 6.25, 3. , 3.25, 3.5 , 3.75])
  1287. Complex interpolation:
  1288. >>> x = [1.5, 4.0]
  1289. >>> xp = [2,3,5]
  1290. >>> fp = [1.0j, 0, 2+3j]
  1291. >>> np.interp(x, xp, fp)
  1292. array([0.+1.j , 1.+1.5j])
  1293. """
  1294. fp = np.asarray(fp)
  1295. if np.iscomplexobj(fp):
  1296. interp_func = compiled_interp_complex
  1297. input_dtype = np.complex128
  1298. else:
  1299. interp_func = compiled_interp
  1300. input_dtype = np.float64
  1301. if period is not None:
  1302. if period == 0:
  1303. raise ValueError("period must be a non-zero value")
  1304. period = abs(period)
  1305. left = None
  1306. right = None
  1307. x = np.asarray(x, dtype=np.float64)
  1308. xp = np.asarray(xp, dtype=np.float64)
  1309. fp = np.asarray(fp, dtype=input_dtype)
  1310. if xp.ndim != 1 or fp.ndim != 1:
  1311. raise ValueError("Data points must be 1-D sequences")
  1312. if xp.shape[0] != fp.shape[0]:
  1313. raise ValueError("fp and xp are not of the same length")
  1314. # normalizing periodic boundaries
  1315. x = x % period
  1316. xp = xp % period
  1317. asort_xp = np.argsort(xp)
  1318. xp = xp[asort_xp]
  1319. fp = fp[asort_xp]
  1320. xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period))
  1321. fp = np.concatenate((fp[-1:], fp, fp[0:1]))
  1322. return interp_func(x, xp, fp, left, right)
  1323. def _angle_dispatcher(z, deg=None):
  1324. return (z,)
  1325. @array_function_dispatch(_angle_dispatcher)
  1326. def angle(z, deg=False):
  1327. """
  1328. Return the angle of the complex argument.
  1329. Parameters
  1330. ----------
  1331. z : array_like
  1332. A complex number or sequence of complex numbers.
  1333. deg : bool, optional
  1334. Return angle in degrees if True, radians if False (default).
  1335. Returns
  1336. -------
  1337. angle : ndarray or scalar
  1338. The counterclockwise angle from the positive real axis on the complex
  1339. plane in the range ``(-pi, pi]``, with dtype as numpy.float64.
  1340. .. versionchanged:: 1.16.0
  1341. This function works on subclasses of ndarray like `ma.array`.
  1342. See Also
  1343. --------
  1344. arctan2
  1345. absolute
  1346. Notes
  1347. -----
  1348. Although the angle of the complex number 0 is undefined, ``numpy.angle(0)``
  1349. returns the value 0.
  1350. Examples
  1351. --------
  1352. >>> np.angle([1.0, 1.0j, 1+1j]) # in radians
  1353. array([ 0. , 1.57079633, 0.78539816]) # may vary
  1354. >>> np.angle(1+1j, deg=True) # in degrees
  1355. 45.0
  1356. """
  1357. z = asanyarray(z)
  1358. if issubclass(z.dtype.type, _nx.complexfloating):
  1359. zimag = z.imag
  1360. zreal = z.real
  1361. else:
  1362. zimag = 0
  1363. zreal = z
  1364. a = arctan2(zimag, zreal)
  1365. if deg:
  1366. a *= 180/pi
  1367. return a
  1368. def _unwrap_dispatcher(p, discont=None, axis=None, *, period=None):
  1369. return (p,)
  1370. @array_function_dispatch(_unwrap_dispatcher)
  1371. def unwrap(p, discont=None, axis=-1, *, period=2*pi):
  1372. r"""
  1373. Unwrap by taking the complement of large deltas with respect to the period.
  1374. This unwraps a signal `p` by changing elements which have an absolute
  1375. difference from their predecessor of more than ``max(discont, period/2)``
  1376. to their `period`-complementary values.
  1377. For the default case where `period` is :math:`2\pi` and `discont` is
  1378. :math:`\pi`, this unwraps a radian phase `p` such that adjacent differences
  1379. are never greater than :math:`\pi` by adding :math:`2k\pi` for some
  1380. integer :math:`k`.
  1381. Parameters
  1382. ----------
  1383. p : array_like
  1384. Input array.
  1385. discont : float, optional
  1386. Maximum discontinuity between values, default is ``period/2``.
  1387. Values below ``period/2`` are treated as if they were ``period/2``.
  1388. To have an effect different from the default, `discont` should be
  1389. larger than ``period/2``.
  1390. axis : int, optional
  1391. Axis along which unwrap will operate, default is the last axis.
  1392. period : float, optional
  1393. Size of the range over which the input wraps. By default, it is
  1394. ``2 pi``.
  1395. .. versionadded:: 1.21.0
  1396. Returns
  1397. -------
  1398. out : ndarray
  1399. Output array.
  1400. See Also
  1401. --------
  1402. rad2deg, deg2rad
  1403. Notes
  1404. -----
  1405. If the discontinuity in `p` is smaller than ``period/2``,
  1406. but larger than `discont`, no unwrapping is done because taking
  1407. the complement would only make the discontinuity larger.
  1408. Examples
  1409. --------
  1410. >>> phase = np.linspace(0, np.pi, num=5)
  1411. >>> phase[3:] += np.pi
  1412. >>> phase
  1413. array([ 0. , 0.78539816, 1.57079633, 5.49778714, 6.28318531]) # may vary
  1414. >>> np.unwrap(phase)
  1415. array([ 0. , 0.78539816, 1.57079633, -0.78539816, 0. ]) # may vary
  1416. >>> np.unwrap([0, 1, 2, -1, 0], period=4)
  1417. array([0, 1, 2, 3, 4])
  1418. >>> np.unwrap([ 1, 2, 3, 4, 5, 6, 1, 2, 3], period=6)
  1419. array([1, 2, 3, 4, 5, 6, 7, 8, 9])
  1420. >>> np.unwrap([2, 3, 4, 5, 2, 3, 4, 5], period=4)
  1421. array([2, 3, 4, 5, 6, 7, 8, 9])
  1422. >>> phase_deg = np.mod(np.linspace(0 ,720, 19), 360) - 180
  1423. >>> np.unwrap(phase_deg, period=360)
  1424. array([-180., -140., -100., -60., -20., 20., 60., 100., 140.,
  1425. 180., 220., 260., 300., 340., 380., 420., 460., 500.,
  1426. 540.])
  1427. """
  1428. p = asarray(p)
  1429. nd = p.ndim
  1430. dd = diff(p, axis=axis)
  1431. if discont is None:
  1432. discont = period/2
  1433. slice1 = [slice(None, None)]*nd # full slices
  1434. slice1[axis] = slice(1, None)
  1435. slice1 = tuple(slice1)
  1436. dtype = np.result_type(dd, period)
  1437. if _nx.issubdtype(dtype, _nx.integer):
  1438. interval_high, rem = divmod(period, 2)
  1439. boundary_ambiguous = rem == 0
  1440. else:
  1441. interval_high = period / 2
  1442. boundary_ambiguous = True
  1443. interval_low = -interval_high
  1444. ddmod = mod(dd - interval_low, period) + interval_low
  1445. if boundary_ambiguous:
  1446. # for `mask = (abs(dd) == period/2)`, the above line made
  1447. # `ddmod[mask] == -period/2`. correct these such that
  1448. # `ddmod[mask] == sign(dd[mask])*period/2`.
  1449. _nx.copyto(ddmod, interval_high,
  1450. where=(ddmod == interval_low) & (dd > 0))
  1451. ph_correct = ddmod - dd
  1452. _nx.copyto(ph_correct, 0, where=abs(dd) < discont)
  1453. up = array(p, copy=True, dtype=dtype)
  1454. up[slice1] = p[slice1] + ph_correct.cumsum(axis)
  1455. return up
  1456. def _sort_complex(a):
  1457. return (a,)
  1458. @array_function_dispatch(_sort_complex)
  1459. def sort_complex(a):
  1460. """
  1461. Sort a complex array using the real part first, then the imaginary part.
  1462. Parameters
  1463. ----------
  1464. a : array_like
  1465. Input array
  1466. Returns
  1467. -------
  1468. out : complex ndarray
  1469. Always returns a sorted complex array.
  1470. Examples
  1471. --------
  1472. >>> np.sort_complex([5, 3, 6, 2, 1])
  1473. array([1.+0.j, 2.+0.j, 3.+0.j, 5.+0.j, 6.+0.j])
  1474. >>> np.sort_complex([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j])
  1475. array([1.+2.j, 2.-1.j, 3.-3.j, 3.-2.j, 3.+5.j])
  1476. """
  1477. b = array(a, copy=True)
  1478. b.sort()
  1479. if not issubclass(b.dtype.type, _nx.complexfloating):
  1480. if b.dtype.char in 'bhBH':
  1481. return b.astype('F')
  1482. elif b.dtype.char == 'g':
  1483. return b.astype('G')
  1484. else:
  1485. return b.astype('D')
  1486. else:
  1487. return b
  1488. def _trim_zeros(filt, trim=None):
  1489. return (filt,)
  1490. @array_function_dispatch(_trim_zeros)
  1491. def trim_zeros(filt, trim='fb'):
  1492. """
  1493. Trim the leading and/or trailing zeros from a 1-D array or sequence.
  1494. Parameters
  1495. ----------
  1496. filt : 1-D array or sequence
  1497. Input array.
  1498. trim : str, optional
  1499. A string with 'f' representing trim from front and 'b' to trim from
  1500. back. Default is 'fb', trim zeros from both front and back of the
  1501. array.
  1502. Returns
  1503. -------
  1504. trimmed : 1-D array or sequence
  1505. The result of trimming the input. The input data type is preserved.
  1506. Examples
  1507. --------
  1508. >>> a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0))
  1509. >>> np.trim_zeros(a)
  1510. array([1, 2, 3, 0, 2, 1])
  1511. >>> np.trim_zeros(a, 'b')
  1512. array([0, 0, 0, ..., 0, 2, 1])
  1513. The input data type is preserved, list/tuple in means list/tuple out.
  1514. >>> np.trim_zeros([0, 1, 2, 0])
  1515. [1, 2]
  1516. """
  1517. first = 0
  1518. trim = trim.upper()
  1519. if 'F' in trim:
  1520. for i in filt:
  1521. if i != 0.:
  1522. break
  1523. else:
  1524. first = first + 1
  1525. last = len(filt)
  1526. if 'B' in trim:
  1527. for i in filt[::-1]:
  1528. if i != 0.:
  1529. break
  1530. else:
  1531. last = last - 1
  1532. return filt[first:last]
  1533. def _extract_dispatcher(condition, arr):
  1534. return (condition, arr)
  1535. @array_function_dispatch(_extract_dispatcher)
  1536. def extract(condition, arr):
  1537. """
  1538. Return the elements of an array that satisfy some condition.
  1539. This is equivalent to ``np.compress(ravel(condition), ravel(arr))``. If
  1540. `condition` is boolean ``np.extract`` is equivalent to ``arr[condition]``.
  1541. Note that `place` does the exact opposite of `extract`.
  1542. Parameters
  1543. ----------
  1544. condition : array_like
  1545. An array whose nonzero or True entries indicate the elements of `arr`
  1546. to extract.
  1547. arr : array_like
  1548. Input array of the same size as `condition`.
  1549. Returns
  1550. -------
  1551. extract : ndarray
  1552. Rank 1 array of values from `arr` where `condition` is True.
  1553. See Also
  1554. --------
  1555. take, put, copyto, compress, place
  1556. Examples
  1557. --------
  1558. >>> arr = np.arange(12).reshape((3, 4))
  1559. >>> arr
  1560. array([[ 0, 1, 2, 3],
  1561. [ 4, 5, 6, 7],
  1562. [ 8, 9, 10, 11]])
  1563. >>> condition = np.mod(arr, 3)==0
  1564. >>> condition
  1565. array([[ True, False, False, True],
  1566. [False, False, True, False],
  1567. [False, True, False, False]])
  1568. >>> np.extract(condition, arr)
  1569. array([0, 3, 6, 9])
  1570. If `condition` is boolean:
  1571. >>> arr[condition]
  1572. array([0, 3, 6, 9])
  1573. """
  1574. return _nx.take(ravel(arr), nonzero(ravel(condition))[0])
  1575. def _place_dispatcher(arr, mask, vals):
  1576. return (arr, mask, vals)
  1577. @array_function_dispatch(_place_dispatcher)
  1578. def place(arr, mask, vals):
  1579. """
  1580. Change elements of an array based on conditional and input values.
  1581. Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that
  1582. `place` uses the first N elements of `vals`, where N is the number of
  1583. True values in `mask`, while `copyto` uses the elements where `mask`
  1584. is True.
  1585. Note that `extract` does the exact opposite of `place`.
  1586. Parameters
  1587. ----------
  1588. arr : ndarray
  1589. Array to put data into.
  1590. mask : array_like
  1591. Boolean mask array. Must have the same size as `a`.
  1592. vals : 1-D sequence
  1593. Values to put into `a`. Only the first N elements are used, where
  1594. N is the number of True values in `mask`. If `vals` is smaller
  1595. than N, it will be repeated, and if elements of `a` are to be masked,
  1596. this sequence must be non-empty.
  1597. See Also
  1598. --------
  1599. copyto, put, take, extract
  1600. Examples
  1601. --------
  1602. >>> arr = np.arange(6).reshape(2, 3)
  1603. >>> np.place(arr, arr>2, [44, 55])
  1604. >>> arr
  1605. array([[ 0, 1, 2],
  1606. [44, 55, 44]])
  1607. """
  1608. return _place(arr, mask, vals)
  1609. def disp(mesg, device=None, linefeed=True):
  1610. """
  1611. Display a message on a device.
  1612. Parameters
  1613. ----------
  1614. mesg : str
  1615. Message to display.
  1616. device : object
  1617. Device to write message. If None, defaults to ``sys.stdout`` which is
  1618. very similar to ``print``. `device` needs to have ``write()`` and
  1619. ``flush()`` methods.
  1620. linefeed : bool, optional
  1621. Option whether to print a line feed or not. Defaults to True.
  1622. Raises
  1623. ------
  1624. AttributeError
  1625. If `device` does not have a ``write()`` or ``flush()`` method.
  1626. Examples
  1627. --------
  1628. Besides ``sys.stdout``, a file-like object can also be used as it has
  1629. both required methods:
  1630. >>> from io import StringIO
  1631. >>> buf = StringIO()
  1632. >>> np.disp(u'"Display" in a file', device=buf)
  1633. >>> buf.getvalue()
  1634. '"Display" in a file\\n'
  1635. """
  1636. if device is None:
  1637. device = sys.stdout
  1638. if linefeed:
  1639. device.write('%s\n' % mesg)
  1640. else:
  1641. device.write('%s' % mesg)
  1642. device.flush()
  1643. return
  1644. # See https://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html
  1645. _DIMENSION_NAME = r'\w+'
  1646. _CORE_DIMENSION_LIST = '(?:{0:}(?:,{0:})*)?'.format(_DIMENSION_NAME)
  1647. _ARGUMENT = r'\({}\)'.format(_CORE_DIMENSION_LIST)
  1648. _ARGUMENT_LIST = '{0:}(?:,{0:})*'.format(_ARGUMENT)
  1649. _SIGNATURE = '^{0:}->{0:}$'.format(_ARGUMENT_LIST)
  1650. def _parse_gufunc_signature(signature):
  1651. """
  1652. Parse string signatures for a generalized universal function.
  1653. Arguments
  1654. ---------
  1655. signature : string
  1656. Generalized universal function signature, e.g., ``(m,n),(n,p)->(m,p)``
  1657. for ``np.matmul``.
  1658. Returns
  1659. -------
  1660. Tuple of input and output core dimensions parsed from the signature, each
  1661. of the form List[Tuple[str, ...]].
  1662. """
  1663. signature = re.sub(r'\s+', '', signature)
  1664. if not re.match(_SIGNATURE, signature):
  1665. raise ValueError(
  1666. 'not a valid gufunc signature: {}'.format(signature))
  1667. return tuple([tuple(re.findall(_DIMENSION_NAME, arg))
  1668. for arg in re.findall(_ARGUMENT, arg_list)]
  1669. for arg_list in signature.split('->'))
  1670. def _update_dim_sizes(dim_sizes, arg, core_dims):
  1671. """
  1672. Incrementally check and update core dimension sizes for a single argument.
  1673. Arguments
  1674. ---------
  1675. dim_sizes : Dict[str, int]
  1676. Sizes of existing core dimensions. Will be updated in-place.
  1677. arg : ndarray
  1678. Argument to examine.
  1679. core_dims : Tuple[str, ...]
  1680. Core dimensions for this argument.
  1681. """
  1682. if not core_dims:
  1683. return
  1684. num_core_dims = len(core_dims)
  1685. if arg.ndim < num_core_dims:
  1686. raise ValueError(
  1687. '%d-dimensional argument does not have enough '
  1688. 'dimensions for all core dimensions %r'
  1689. % (arg.ndim, core_dims))
  1690. core_shape = arg.shape[-num_core_dims:]
  1691. for dim, size in zip(core_dims, core_shape):
  1692. if dim in dim_sizes:
  1693. if size != dim_sizes[dim]:
  1694. raise ValueError(
  1695. 'inconsistent size for core dimension %r: %r vs %r'
  1696. % (dim, size, dim_sizes[dim]))
  1697. else:
  1698. dim_sizes[dim] = size
  1699. def _parse_input_dimensions(args, input_core_dims):
  1700. """
  1701. Parse broadcast and core dimensions for vectorize with a signature.
  1702. Arguments
  1703. ---------
  1704. args : Tuple[ndarray, ...]
  1705. Tuple of input arguments to examine.
  1706. input_core_dims : List[Tuple[str, ...]]
  1707. List of core dimensions corresponding to each input.
  1708. Returns
  1709. -------
  1710. broadcast_shape : Tuple[int, ...]
  1711. Common shape to broadcast all non-core dimensions to.
  1712. dim_sizes : Dict[str, int]
  1713. Common sizes for named core dimensions.
  1714. """
  1715. broadcast_args = []
  1716. dim_sizes = {}
  1717. for arg, core_dims in zip(args, input_core_dims):
  1718. _update_dim_sizes(dim_sizes, arg, core_dims)
  1719. ndim = arg.ndim - len(core_dims)
  1720. dummy_array = np.lib.stride_tricks.as_strided(0, arg.shape[:ndim])
  1721. broadcast_args.append(dummy_array)
  1722. broadcast_shape = np.lib.stride_tricks._broadcast_shape(*broadcast_args)
  1723. return broadcast_shape, dim_sizes
  1724. def _calculate_shapes(broadcast_shape, dim_sizes, list_of_core_dims):
  1725. """Helper for calculating broadcast shapes with core dimensions."""
  1726. return [broadcast_shape + tuple(dim_sizes[dim] for dim in core_dims)
  1727. for core_dims in list_of_core_dims]
  1728. def _create_arrays(broadcast_shape, dim_sizes, list_of_core_dims, dtypes,
  1729. results=None):
  1730. """Helper for creating output arrays in vectorize."""
  1731. shapes = _calculate_shapes(broadcast_shape, dim_sizes, list_of_core_dims)
  1732. if dtypes is None:
  1733. dtypes = [None] * len(shapes)
  1734. if results is None:
  1735. arrays = tuple(np.empty(shape=shape, dtype=dtype)
  1736. for shape, dtype in zip(shapes, dtypes))
  1737. else:
  1738. arrays = tuple(np.empty_like(result, shape=shape, dtype=dtype)
  1739. for result, shape, dtype
  1740. in zip(results, shapes, dtypes))
  1741. return arrays
  1742. @set_module('numpy')
  1743. class vectorize:
  1744. """
  1745. vectorize(pyfunc=np._NoValue, otypes=None, doc=None, excluded=None,
  1746. cache=False, signature=None)
  1747. Returns an object that acts like pyfunc, but takes arrays as input.
  1748. Define a vectorized function which takes a nested sequence of objects or
  1749. numpy arrays as inputs and returns a single numpy array or a tuple of numpy
  1750. arrays. The vectorized function evaluates `pyfunc` over successive tuples
  1751. of the input arrays like the python map function, except it uses the
  1752. broadcasting rules of numpy.
  1753. The data type of the output of `vectorized` is determined by calling
  1754. the function with the first element of the input. This can be avoided
  1755. by specifying the `otypes` argument.
  1756. Parameters
  1757. ----------
  1758. pyfunc : callable, optional
  1759. A python function or method.
  1760. Can be omitted to produce a decorator with keyword arguments.
  1761. otypes : str or list of dtypes, optional
  1762. The output data type. It must be specified as either a string of
  1763. typecode characters or a list of data type specifiers. There should
  1764. be one data type specifier for each output.
  1765. doc : str, optional
  1766. The docstring for the function. If None, the docstring will be the
  1767. ``pyfunc.__doc__``.
  1768. excluded : set, optional
  1769. Set of strings or integers representing the positional or keyword
  1770. arguments for which the function will not be vectorized. These will be
  1771. passed directly to `pyfunc` unmodified.
  1772. .. versionadded:: 1.7.0
  1773. cache : bool, optional
  1774. If `True`, then cache the first function call that determines the number
  1775. of outputs if `otypes` is not provided.
  1776. .. versionadded:: 1.7.0
  1777. signature : string, optional
  1778. Generalized universal function signature, e.g., ``(m,n),(n)->(m)`` for
  1779. vectorized matrix-vector multiplication. If provided, ``pyfunc`` will
  1780. be called with (and expected to return) arrays with shapes given by the
  1781. size of corresponding core dimensions. By default, ``pyfunc`` is
  1782. assumed to take scalars as input and output.
  1783. .. versionadded:: 1.12.0
  1784. Returns
  1785. -------
  1786. out : callable
  1787. A vectorized function if ``pyfunc`` was provided,
  1788. a decorator otherwise.
  1789. See Also
  1790. --------
  1791. frompyfunc : Takes an arbitrary Python function and returns a ufunc
  1792. Notes
  1793. -----
  1794. The `vectorize` function is provided primarily for convenience, not for
  1795. performance. The implementation is essentially a for loop.
  1796. If `otypes` is not specified, then a call to the function with the
  1797. first argument will be used to determine the number of outputs. The
  1798. results of this call will be cached if `cache` is `True` to prevent
  1799. calling the function twice. However, to implement the cache, the
  1800. original function must be wrapped which will slow down subsequent
  1801. calls, so only do this if your function is expensive.
  1802. The new keyword argument interface and `excluded` argument support
  1803. further degrades performance.
  1804. References
  1805. ----------
  1806. .. [1] :doc:`/reference/c-api/generalized-ufuncs`
  1807. Examples
  1808. --------
  1809. >>> def myfunc(a, b):
  1810. ... "Return a-b if a>b, otherwise return a+b"
  1811. ... if a > b:
  1812. ... return a - b
  1813. ... else:
  1814. ... return a + b
  1815. >>> vfunc = np.vectorize(myfunc)
  1816. >>> vfunc([1, 2, 3, 4], 2)
  1817. array([3, 4, 1, 2])
  1818. The docstring is taken from the input function to `vectorize` unless it
  1819. is specified:
  1820. >>> vfunc.__doc__
  1821. 'Return a-b if a>b, otherwise return a+b'
  1822. >>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`')
  1823. >>> vfunc.__doc__
  1824. 'Vectorized `myfunc`'
  1825. The output type is determined by evaluating the first element of the input,
  1826. unless it is specified:
  1827. >>> out = vfunc([1, 2, 3, 4], 2)
  1828. >>> type(out[0])
  1829. <class 'numpy.int64'>
  1830. >>> vfunc = np.vectorize(myfunc, otypes=[float])
  1831. >>> out = vfunc([1, 2, 3, 4], 2)
  1832. >>> type(out[0])
  1833. <class 'numpy.float64'>
  1834. The `excluded` argument can be used to prevent vectorizing over certain
  1835. arguments. This can be useful for array-like arguments of a fixed length
  1836. such as the coefficients for a polynomial as in `polyval`:
  1837. >>> def mypolyval(p, x):
  1838. ... _p = list(p)
  1839. ... res = _p.pop(0)
  1840. ... while _p:
  1841. ... res = res*x + _p.pop(0)
  1842. ... return res
  1843. >>> vpolyval = np.vectorize(mypolyval, excluded=['p'])
  1844. >>> vpolyval(p=[1, 2, 3], x=[0, 1])
  1845. array([3, 6])
  1846. Positional arguments may also be excluded by specifying their position:
  1847. >>> vpolyval.excluded.add(0)
  1848. >>> vpolyval([1, 2, 3], x=[0, 1])
  1849. array([3, 6])
  1850. The `signature` argument allows for vectorizing functions that act on
  1851. non-scalar arrays of fixed length. For example, you can use it for a
  1852. vectorized calculation of Pearson correlation coefficient and its p-value:
  1853. >>> import scipy.stats
  1854. >>> pearsonr = np.vectorize(scipy.stats.pearsonr,
  1855. ... signature='(n),(n)->(),()')
  1856. >>> pearsonr([[0, 1, 2, 3]], [[1, 2, 3, 4], [4, 3, 2, 1]])
  1857. (array([ 1., -1.]), array([ 0., 0.]))
  1858. Or for a vectorized convolution:
  1859. >>> convolve = np.vectorize(np.convolve, signature='(n),(m)->(k)')
  1860. >>> convolve(np.eye(4), [1, 2, 1])
  1861. array([[1., 2., 1., 0., 0., 0.],
  1862. [0., 1., 2., 1., 0., 0.],
  1863. [0., 0., 1., 2., 1., 0.],
  1864. [0., 0., 0., 1., 2., 1.]])
  1865. Decorator syntax is supported. The decorator can be called as
  1866. a function to provide keyword arguments.
  1867. >>>@np.vectorize
  1868. ...def identity(x):
  1869. ... return x
  1870. ...
  1871. >>>identity([0, 1, 2])
  1872. array([0, 1, 2])
  1873. >>>@np.vectorize(otypes=[float])
  1874. ...def as_float(x):
  1875. ... return x
  1876. ...
  1877. >>>as_float([0, 1, 2])
  1878. array([0., 1., 2.])
  1879. """
  1880. def __init__(self, pyfunc=np._NoValue, otypes=None, doc=None,
  1881. excluded=None, cache=False, signature=None):
  1882. if (pyfunc != np._NoValue) and (not callable(pyfunc)):
  1883. #Splitting the error message to keep
  1884. #the length below 79 characters.
  1885. part1 = "When used as a decorator, "
  1886. part2 = "only accepts keyword arguments."
  1887. raise TypeError(part1 + part2)
  1888. self.pyfunc = pyfunc
  1889. self.cache = cache
  1890. self.signature = signature
  1891. if pyfunc != np._NoValue and hasattr(pyfunc, '__name__'):
  1892. self.__name__ = pyfunc.__name__
  1893. self._ufunc = {} # Caching to improve default performance
  1894. self._doc = None
  1895. self.__doc__ = doc
  1896. if doc is None and hasattr(pyfunc, '__doc__'):
  1897. self.__doc__ = pyfunc.__doc__
  1898. else:
  1899. self._doc = doc
  1900. if isinstance(otypes, str):
  1901. for char in otypes:
  1902. if char not in typecodes['All']:
  1903. raise ValueError("Invalid otype specified: %s" % (char,))
  1904. elif iterable(otypes):
  1905. otypes = ''.join([_nx.dtype(x).char for x in otypes])
  1906. elif otypes is not None:
  1907. raise ValueError("Invalid otype specification")
  1908. self.otypes = otypes
  1909. # Excluded variable support
  1910. if excluded is None:
  1911. excluded = set()
  1912. self.excluded = set(excluded)
  1913. if signature is not None:
  1914. self._in_and_out_core_dims = _parse_gufunc_signature(signature)
  1915. else:
  1916. self._in_and_out_core_dims = None
  1917. def _init_stage_2(self, pyfunc, *args, **kwargs):
  1918. self.__name__ = pyfunc.__name__
  1919. self.pyfunc = pyfunc
  1920. if self._doc is None:
  1921. self.__doc__ = pyfunc.__doc__
  1922. else:
  1923. self.__doc__ = self._doc
  1924. def _call_as_normal(self, *args, **kwargs):
  1925. """
  1926. Return arrays with the results of `pyfunc` broadcast (vectorized) over
  1927. `args` and `kwargs` not in `excluded`.
  1928. """
  1929. excluded = self.excluded
  1930. if not kwargs and not excluded:
  1931. func = self.pyfunc
  1932. vargs = args
  1933. else:
  1934. # The wrapper accepts only positional arguments: we use `names` and
  1935. # `inds` to mutate `the_args` and `kwargs` to pass to the original
  1936. # function.
  1937. nargs = len(args)
  1938. names = [_n for _n in kwargs if _n not in excluded]
  1939. inds = [_i for _i in range(nargs) if _i not in excluded]
  1940. the_args = list(args)
  1941. def func(*vargs):
  1942. for _n, _i in enumerate(inds):
  1943. the_args[_i] = vargs[_n]
  1944. kwargs.update(zip(names, vargs[len(inds):]))
  1945. return self.pyfunc(*the_args, **kwargs)
  1946. vargs = [args[_i] for _i in inds]
  1947. vargs.extend([kwargs[_n] for _n in names])
  1948. return self._vectorize_call(func=func, args=vargs)
  1949. def __call__(self, *args, **kwargs):
  1950. if self.pyfunc is np._NoValue:
  1951. self._init_stage_2(*args, **kwargs)
  1952. return self
  1953. return self._call_as_normal(*args, **kwargs)
  1954. def _get_ufunc_and_otypes(self, func, args):
  1955. """Return (ufunc, otypes)."""
  1956. # frompyfunc will fail if args is empty
  1957. if not args:
  1958. raise ValueError('args can not be empty')
  1959. if self.otypes is not None:
  1960. otypes = self.otypes
  1961. # self._ufunc is a dictionary whose keys are the number of
  1962. # arguments (i.e. len(args)) and whose values are ufuncs created
  1963. # by frompyfunc. len(args) can be different for different calls if
  1964. # self.pyfunc has parameters with default values. We only use the
  1965. # cache when func is self.pyfunc, which occurs when the call uses
  1966. # only positional arguments and no arguments are excluded.
  1967. nin = len(args)
  1968. nout = len(self.otypes)
  1969. if func is not self.pyfunc or nin not in self._ufunc:
  1970. ufunc = frompyfunc(func, nin, nout)
  1971. else:
  1972. ufunc = None # We'll get it from self._ufunc
  1973. if func is self.pyfunc:
  1974. ufunc = self._ufunc.setdefault(nin, ufunc)
  1975. else:
  1976. # Get number of outputs and output types by calling the function on
  1977. # the first entries of args. We also cache the result to prevent
  1978. # the subsequent call when the ufunc is evaluated.
  1979. # Assumes that ufunc first evaluates the 0th elements in the input
  1980. # arrays (the input values are not checked to ensure this)
  1981. args = [asarray(arg) for arg in args]
  1982. if builtins.any(arg.size == 0 for arg in args):
  1983. raise ValueError('cannot call `vectorize` on size 0 inputs '
  1984. 'unless `otypes` is set')
  1985. inputs = [arg.flat[0] for arg in args]
  1986. outputs = func(*inputs)
  1987. # Performance note: profiling indicates that -- for simple
  1988. # functions at least -- this wrapping can almost double the
  1989. # execution time.
  1990. # Hence we make it optional.
  1991. if self.cache:
  1992. _cache = [outputs]
  1993. def _func(*vargs):
  1994. if _cache:
  1995. return _cache.pop()
  1996. else:
  1997. return func(*vargs)
  1998. else:
  1999. _func = func
  2000. if isinstance(outputs, tuple):
  2001. nout = len(outputs)
  2002. else:
  2003. nout = 1
  2004. outputs = (outputs,)
  2005. otypes = ''.join([asarray(outputs[_k]).dtype.char
  2006. for _k in range(nout)])
  2007. # Performance note: profiling indicates that creating the ufunc is
  2008. # not a significant cost compared with wrapping so it seems not
  2009. # worth trying to cache this.
  2010. ufunc = frompyfunc(_func, len(args), nout)
  2011. return ufunc, otypes
  2012. def _vectorize_call(self, func, args):
  2013. """Vectorized call to `func` over positional `args`."""
  2014. if self.signature is not None:
  2015. res = self._vectorize_call_with_signature(func, args)
  2016. elif not args:
  2017. res = func()
  2018. else:
  2019. ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
  2020. # Convert args to object arrays first
  2021. inputs = [asanyarray(a, dtype=object) for a in args]
  2022. outputs = ufunc(*inputs)
  2023. if ufunc.nout == 1:
  2024. res = asanyarray(outputs, dtype=otypes[0])
  2025. else:
  2026. res = tuple([asanyarray(x, dtype=t)
  2027. for x, t in zip(outputs, otypes)])
  2028. return res
  2029. def _vectorize_call_with_signature(self, func, args):
  2030. """Vectorized call over positional arguments with a signature."""
  2031. input_core_dims, output_core_dims = self._in_and_out_core_dims
  2032. if len(args) != len(input_core_dims):
  2033. raise TypeError('wrong number of positional arguments: '
  2034. 'expected %r, got %r'
  2035. % (len(input_core_dims), len(args)))
  2036. args = tuple(asanyarray(arg) for arg in args)
  2037. broadcast_shape, dim_sizes = _parse_input_dimensions(
  2038. args, input_core_dims)
  2039. input_shapes = _calculate_shapes(broadcast_shape, dim_sizes,
  2040. input_core_dims)
  2041. args = [np.broadcast_to(arg, shape, subok=True)
  2042. for arg, shape in zip(args, input_shapes)]
  2043. outputs = None
  2044. otypes = self.otypes
  2045. nout = len(output_core_dims)
  2046. for index in np.ndindex(*broadcast_shape):
  2047. results = func(*(arg[index] for arg in args))
  2048. n_results = len(results) if isinstance(results, tuple) else 1
  2049. if nout != n_results:
  2050. raise ValueError(
  2051. 'wrong number of outputs from pyfunc: expected %r, got %r'
  2052. % (nout, n_results))
  2053. if nout == 1:
  2054. results = (results,)
  2055. if outputs is None:
  2056. for result, core_dims in zip(results, output_core_dims):
  2057. _update_dim_sizes(dim_sizes, result, core_dims)
  2058. outputs = _create_arrays(broadcast_shape, dim_sizes,
  2059. output_core_dims, otypes, results)
  2060. for output, result in zip(outputs, results):
  2061. output[index] = result
  2062. if outputs is None:
  2063. # did not call the function even once
  2064. if otypes is None:
  2065. raise ValueError('cannot call `vectorize` on size 0 inputs '
  2066. 'unless `otypes` is set')
  2067. if builtins.any(dim not in dim_sizes
  2068. for dims in output_core_dims
  2069. for dim in dims):
  2070. raise ValueError('cannot call `vectorize` with a signature '
  2071. 'including new output dimensions on size 0 '
  2072. 'inputs')
  2073. outputs = _create_arrays(broadcast_shape, dim_sizes,
  2074. output_core_dims, otypes)
  2075. return outputs[0] if nout == 1 else outputs
  2076. def _cov_dispatcher(m, y=None, rowvar=None, bias=None, ddof=None,
  2077. fweights=None, aweights=None, *, dtype=None):
  2078. return (m, y, fweights, aweights)
  2079. @array_function_dispatch(_cov_dispatcher)
  2080. def cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None,
  2081. aweights=None, *, dtype=None):
  2082. """
  2083. Estimate a covariance matrix, given data and weights.
  2084. Covariance indicates the level to which two variables vary together.
  2085. If we examine N-dimensional samples, :math:`X = [x_1, x_2, ... x_N]^T`,
  2086. then the covariance matrix element :math:`C_{ij}` is the covariance of
  2087. :math:`x_i` and :math:`x_j`. The element :math:`C_{ii}` is the variance
  2088. of :math:`x_i`.
  2089. See the notes for an outline of the algorithm.
  2090. Parameters
  2091. ----------
  2092. m : array_like
  2093. A 1-D or 2-D array containing multiple variables and observations.
  2094. Each row of `m` represents a variable, and each column a single
  2095. observation of all those variables. Also see `rowvar` below.
  2096. y : array_like, optional
  2097. An additional set of variables and observations. `y` has the same form
  2098. as that of `m`.
  2099. rowvar : bool, optional
  2100. If `rowvar` is True (default), then each row represents a
  2101. variable, with observations in the columns. Otherwise, the relationship
  2102. is transposed: each column represents a variable, while the rows
  2103. contain observations.
  2104. bias : bool, optional
  2105. Default normalization (False) is by ``(N - 1)``, where ``N`` is the
  2106. number of observations given (unbiased estimate). If `bias` is True,
  2107. then normalization is by ``N``. These values can be overridden by using
  2108. the keyword ``ddof`` in numpy versions >= 1.5.
  2109. ddof : int, optional
  2110. If not ``None`` the default value implied by `bias` is overridden.
  2111. Note that ``ddof=1`` will return the unbiased estimate, even if both
  2112. `fweights` and `aweights` are specified, and ``ddof=0`` will return
  2113. the simple average. See the notes for the details. The default value
  2114. is ``None``.
  2115. .. versionadded:: 1.5
  2116. fweights : array_like, int, optional
  2117. 1-D array of integer frequency weights; the number of times each
  2118. observation vector should be repeated.
  2119. .. versionadded:: 1.10
  2120. aweights : array_like, optional
  2121. 1-D array of observation vector weights. These relative weights are
  2122. typically large for observations considered "important" and smaller for
  2123. observations considered less "important". If ``ddof=0`` the array of
  2124. weights can be used to assign probabilities to observation vectors.
  2125. .. versionadded:: 1.10
  2126. dtype : data-type, optional
  2127. Data-type of the result. By default, the return data-type will have
  2128. at least `numpy.float64` precision.
  2129. .. versionadded:: 1.20
  2130. Returns
  2131. -------
  2132. out : ndarray
  2133. The covariance matrix of the variables.
  2134. See Also
  2135. --------
  2136. corrcoef : Normalized covariance matrix
  2137. Notes
  2138. -----
  2139. Assume that the observations are in the columns of the observation
  2140. array `m` and let ``f = fweights`` and ``a = aweights`` for brevity. The
  2141. steps to compute the weighted covariance are as follows::
  2142. >>> m = np.arange(10, dtype=np.float64)
  2143. >>> f = np.arange(10) * 2
  2144. >>> a = np.arange(10) ** 2.
  2145. >>> ddof = 1
  2146. >>> w = f * a
  2147. >>> v1 = np.sum(w)
  2148. >>> v2 = np.sum(w * a)
  2149. >>> m -= np.sum(m * w, axis=None, keepdims=True) / v1
  2150. >>> cov = np.dot(m * w, m.T) * v1 / (v1**2 - ddof * v2)
  2151. Note that when ``a == 1``, the normalization factor
  2152. ``v1 / (v1**2 - ddof * v2)`` goes over to ``1 / (np.sum(f) - ddof)``
  2153. as it should.
  2154. Examples
  2155. --------
  2156. Consider two variables, :math:`x_0` and :math:`x_1`, which
  2157. correlate perfectly, but in opposite directions:
  2158. >>> x = np.array([[0, 2], [1, 1], [2, 0]]).T
  2159. >>> x
  2160. array([[0, 1, 2],
  2161. [2, 1, 0]])
  2162. Note how :math:`x_0` increases while :math:`x_1` decreases. The covariance
  2163. matrix shows this clearly:
  2164. >>> np.cov(x)
  2165. array([[ 1., -1.],
  2166. [-1., 1.]])
  2167. Note that element :math:`C_{0,1}`, which shows the correlation between
  2168. :math:`x_0` and :math:`x_1`, is negative.
  2169. Further, note how `x` and `y` are combined:
  2170. >>> x = [-2.1, -1, 4.3]
  2171. >>> y = [3, 1.1, 0.12]
  2172. >>> X = np.stack((x, y), axis=0)
  2173. >>> np.cov(X)
  2174. array([[11.71 , -4.286 ], # may vary
  2175. [-4.286 , 2.144133]])
  2176. >>> np.cov(x, y)
  2177. array([[11.71 , -4.286 ], # may vary
  2178. [-4.286 , 2.144133]])
  2179. >>> np.cov(x)
  2180. array(11.71)
  2181. """
  2182. # Check inputs
  2183. if ddof is not None and ddof != int(ddof):
  2184. raise ValueError(
  2185. "ddof must be integer")
  2186. # Handles complex arrays too
  2187. m = np.asarray(m)
  2188. if m.ndim > 2:
  2189. raise ValueError("m has more than 2 dimensions")
  2190. if y is not None:
  2191. y = np.asarray(y)
  2192. if y.ndim > 2:
  2193. raise ValueError("y has more than 2 dimensions")
  2194. if dtype is None:
  2195. if y is None:
  2196. dtype = np.result_type(m, np.float64)
  2197. else:
  2198. dtype = np.result_type(m, y, np.float64)
  2199. X = array(m, ndmin=2, dtype=dtype)
  2200. if not rowvar and X.shape[0] != 1:
  2201. X = X.T
  2202. if X.shape[0] == 0:
  2203. return np.array([]).reshape(0, 0)
  2204. if y is not None:
  2205. y = array(y, copy=False, ndmin=2, dtype=dtype)
  2206. if not rowvar and y.shape[0] != 1:
  2207. y = y.T
  2208. X = np.concatenate((X, y), axis=0)
  2209. if ddof is None:
  2210. if bias == 0:
  2211. ddof = 1
  2212. else:
  2213. ddof = 0
  2214. # Get the product of frequencies and weights
  2215. w = None
  2216. if fweights is not None:
  2217. fweights = np.asarray(fweights, dtype=float)
  2218. if not np.all(fweights == np.around(fweights)):
  2219. raise TypeError(
  2220. "fweights must be integer")
  2221. if fweights.ndim > 1:
  2222. raise RuntimeError(
  2223. "cannot handle multidimensional fweights")
  2224. if fweights.shape[0] != X.shape[1]:
  2225. raise RuntimeError(
  2226. "incompatible numbers of samples and fweights")
  2227. if any(fweights < 0):
  2228. raise ValueError(
  2229. "fweights cannot be negative")
  2230. w = fweights
  2231. if aweights is not None:
  2232. aweights = np.asarray(aweights, dtype=float)
  2233. if aweights.ndim > 1:
  2234. raise RuntimeError(
  2235. "cannot handle multidimensional aweights")
  2236. if aweights.shape[0] != X.shape[1]:
  2237. raise RuntimeError(
  2238. "incompatible numbers of samples and aweights")
  2239. if any(aweights < 0):
  2240. raise ValueError(
  2241. "aweights cannot be negative")
  2242. if w is None:
  2243. w = aweights
  2244. else:
  2245. w *= aweights
  2246. avg, w_sum = average(X, axis=1, weights=w, returned=True)
  2247. w_sum = w_sum[0]
  2248. # Determine the normalization
  2249. if w is None:
  2250. fact = X.shape[1] - ddof
  2251. elif ddof == 0:
  2252. fact = w_sum
  2253. elif aweights is None:
  2254. fact = w_sum - ddof
  2255. else:
  2256. fact = w_sum - ddof*sum(w*aweights)/w_sum
  2257. if fact <= 0:
  2258. warnings.warn("Degrees of freedom <= 0 for slice",
  2259. RuntimeWarning, stacklevel=2)
  2260. fact = 0.0
  2261. X -= avg[:, None]
  2262. if w is None:
  2263. X_T = X.T
  2264. else:
  2265. X_T = (X*w).T
  2266. c = dot(X, X_T.conj())
  2267. c *= np.true_divide(1, fact)
  2268. return c.squeeze()
  2269. def _corrcoef_dispatcher(x, y=None, rowvar=None, bias=None, ddof=None, *,
  2270. dtype=None):
  2271. return (x, y)
  2272. @array_function_dispatch(_corrcoef_dispatcher)
  2273. def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, ddof=np._NoValue, *,
  2274. dtype=None):
  2275. """
  2276. Return Pearson product-moment correlation coefficients.
  2277. Please refer to the documentation for `cov` for more detail. The
  2278. relationship between the correlation coefficient matrix, `R`, and the
  2279. covariance matrix, `C`, is
  2280. .. math:: R_{ij} = \\frac{ C_{ij} } { \\sqrt{ C_{ii} C_{jj} } }
  2281. The values of `R` are between -1 and 1, inclusive.
  2282. Parameters
  2283. ----------
  2284. x : array_like
  2285. A 1-D or 2-D array containing multiple variables and observations.
  2286. Each row of `x` represents a variable, and each column a single
  2287. observation of all those variables. Also see `rowvar` below.
  2288. y : array_like, optional
  2289. An additional set of variables and observations. `y` has the same
  2290. shape as `x`.
  2291. rowvar : bool, optional
  2292. If `rowvar` is True (default), then each row represents a
  2293. variable, with observations in the columns. Otherwise, the relationship
  2294. is transposed: each column represents a variable, while the rows
  2295. contain observations.
  2296. bias : _NoValue, optional
  2297. Has no effect, do not use.
  2298. .. deprecated:: 1.10.0
  2299. ddof : _NoValue, optional
  2300. Has no effect, do not use.
  2301. .. deprecated:: 1.10.0
  2302. dtype : data-type, optional
  2303. Data-type of the result. By default, the return data-type will have
  2304. at least `numpy.float64` precision.
  2305. .. versionadded:: 1.20
  2306. Returns
  2307. -------
  2308. R : ndarray
  2309. The correlation coefficient matrix of the variables.
  2310. See Also
  2311. --------
  2312. cov : Covariance matrix
  2313. Notes
  2314. -----
  2315. Due to floating point rounding the resulting array may not be Hermitian,
  2316. the diagonal elements may not be 1, and the elements may not satisfy the
  2317. inequality abs(a) <= 1. The real and imaginary parts are clipped to the
  2318. interval [-1, 1] in an attempt to improve on that situation but is not
  2319. much help in the complex case.
  2320. This function accepts but discards arguments `bias` and `ddof`. This is
  2321. for backwards compatibility with previous versions of this function. These
  2322. arguments had no effect on the return values of the function and can be
  2323. safely ignored in this and previous versions of numpy.
  2324. Examples
  2325. --------
  2326. In this example we generate two random arrays, ``xarr`` and ``yarr``, and
  2327. compute the row-wise and column-wise Pearson correlation coefficients,
  2328. ``R``. Since ``rowvar`` is true by default, we first find the row-wise
  2329. Pearson correlation coefficients between the variables of ``xarr``.
  2330. >>> import numpy as np
  2331. >>> rng = np.random.default_rng(seed=42)
  2332. >>> xarr = rng.random((3, 3))
  2333. >>> xarr
  2334. array([[0.77395605, 0.43887844, 0.85859792],
  2335. [0.69736803, 0.09417735, 0.97562235],
  2336. [0.7611397 , 0.78606431, 0.12811363]])
  2337. >>> R1 = np.corrcoef(xarr)
  2338. >>> R1
  2339. array([[ 1. , 0.99256089, -0.68080986],
  2340. [ 0.99256089, 1. , -0.76492172],
  2341. [-0.68080986, -0.76492172, 1. ]])
  2342. If we add another set of variables and observations ``yarr``, we can
  2343. compute the row-wise Pearson correlation coefficients between the
  2344. variables in ``xarr`` and ``yarr``.
  2345. >>> yarr = rng.random((3, 3))
  2346. >>> yarr
  2347. array([[0.45038594, 0.37079802, 0.92676499],
  2348. [0.64386512, 0.82276161, 0.4434142 ],
  2349. [0.22723872, 0.55458479, 0.06381726]])
  2350. >>> R2 = np.corrcoef(xarr, yarr)
  2351. >>> R2
  2352. array([[ 1. , 0.99256089, -0.68080986, 0.75008178, -0.934284 ,
  2353. -0.99004057],
  2354. [ 0.99256089, 1. , -0.76492172, 0.82502011, -0.97074098,
  2355. -0.99981569],
  2356. [-0.68080986, -0.76492172, 1. , -0.99507202, 0.89721355,
  2357. 0.77714685],
  2358. [ 0.75008178, 0.82502011, -0.99507202, 1. , -0.93657855,
  2359. -0.83571711],
  2360. [-0.934284 , -0.97074098, 0.89721355, -0.93657855, 1. ,
  2361. 0.97517215],
  2362. [-0.99004057, -0.99981569, 0.77714685, -0.83571711, 0.97517215,
  2363. 1. ]])
  2364. Finally if we use the option ``rowvar=False``, the columns are now
  2365. being treated as the variables and we will find the column-wise Pearson
  2366. correlation coefficients between variables in ``xarr`` and ``yarr``.
  2367. >>> R3 = np.corrcoef(xarr, yarr, rowvar=False)
  2368. >>> R3
  2369. array([[ 1. , 0.77598074, -0.47458546, -0.75078643, -0.9665554 ,
  2370. 0.22423734],
  2371. [ 0.77598074, 1. , -0.92346708, -0.99923895, -0.58826587,
  2372. -0.44069024],
  2373. [-0.47458546, -0.92346708, 1. , 0.93773029, 0.23297648,
  2374. 0.75137473],
  2375. [-0.75078643, -0.99923895, 0.93773029, 1. , 0.55627469,
  2376. 0.47536961],
  2377. [-0.9665554 , -0.58826587, 0.23297648, 0.55627469, 1. ,
  2378. -0.46666491],
  2379. [ 0.22423734, -0.44069024, 0.75137473, 0.47536961, -0.46666491,
  2380. 1. ]])
  2381. """
  2382. if bias is not np._NoValue or ddof is not np._NoValue:
  2383. # 2015-03-15, 1.10
  2384. warnings.warn('bias and ddof have no effect and are deprecated',
  2385. DeprecationWarning, stacklevel=2)
  2386. c = cov(x, y, rowvar, dtype=dtype)
  2387. try:
  2388. d = diag(c)
  2389. except ValueError:
  2390. # scalar covariance
  2391. # nan if incorrect value (nan, inf, 0), 1 otherwise
  2392. return c / c
  2393. stddev = sqrt(d.real)
  2394. c /= stddev[:, None]
  2395. c /= stddev[None, :]
  2396. # Clip real and imaginary parts to [-1, 1]. This does not guarantee
  2397. # abs(a[i,j]) <= 1 for complex arrays, but is the best we can do without
  2398. # excessive work.
  2399. np.clip(c.real, -1, 1, out=c.real)
  2400. if np.iscomplexobj(c):
  2401. np.clip(c.imag, -1, 1, out=c.imag)
  2402. return c
  2403. @set_module('numpy')
  2404. def blackman(M):
  2405. """
  2406. Return the Blackman window.
  2407. The Blackman window is a taper formed by using the first three
  2408. terms of a summation of cosines. It was designed to have close to the
  2409. minimal leakage possible. It is close to optimal, only slightly worse
  2410. than a Kaiser window.
  2411. Parameters
  2412. ----------
  2413. M : int
  2414. Number of points in the output window. If zero or less, an empty
  2415. array is returned.
  2416. Returns
  2417. -------
  2418. out : ndarray
  2419. The window, with the maximum value normalized to one (the value one
  2420. appears only if the number of samples is odd).
  2421. See Also
  2422. --------
  2423. bartlett, hamming, hanning, kaiser
  2424. Notes
  2425. -----
  2426. The Blackman window is defined as
  2427. .. math:: w(n) = 0.42 - 0.5 \\cos(2\\pi n/M) + 0.08 \\cos(4\\pi n/M)
  2428. Most references to the Blackman window come from the signal processing
  2429. literature, where it is used as one of many windowing functions for
  2430. smoothing values. It is also known as an apodization (which means
  2431. "removing the foot", i.e. smoothing discontinuities at the beginning
  2432. and end of the sampled signal) or tapering function. It is known as a
  2433. "near optimal" tapering function, almost as good (by some measures)
  2434. as the kaiser window.
  2435. References
  2436. ----------
  2437. Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra,
  2438. Dover Publications, New York.
  2439. Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing.
  2440. Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471.
  2441. Examples
  2442. --------
  2443. >>> import matplotlib.pyplot as plt
  2444. >>> np.blackman(12)
  2445. array([-1.38777878e-17, 3.26064346e-02, 1.59903635e-01, # may vary
  2446. 4.14397981e-01, 7.36045180e-01, 9.67046769e-01,
  2447. 9.67046769e-01, 7.36045180e-01, 4.14397981e-01,
  2448. 1.59903635e-01, 3.26064346e-02, -1.38777878e-17])
  2449. Plot the window and the frequency response:
  2450. >>> from numpy.fft import fft, fftshift
  2451. >>> window = np.blackman(51)
  2452. >>> plt.plot(window)
  2453. [<matplotlib.lines.Line2D object at 0x...>]
  2454. >>> plt.title("Blackman window")
  2455. Text(0.5, 1.0, 'Blackman window')
  2456. >>> plt.ylabel("Amplitude")
  2457. Text(0, 0.5, 'Amplitude')
  2458. >>> plt.xlabel("Sample")
  2459. Text(0.5, 0, 'Sample')
  2460. >>> plt.show()
  2461. >>> plt.figure()
  2462. <Figure size 640x480 with 0 Axes>
  2463. >>> A = fft(window, 2048) / 25.5
  2464. >>> mag = np.abs(fftshift(A))
  2465. >>> freq = np.linspace(-0.5, 0.5, len(A))
  2466. >>> with np.errstate(divide='ignore', invalid='ignore'):
  2467. ... response = 20 * np.log10(mag)
  2468. ...
  2469. >>> response = np.clip(response, -100, 100)
  2470. >>> plt.plot(freq, response)
  2471. [<matplotlib.lines.Line2D object at 0x...>]
  2472. >>> plt.title("Frequency response of Blackman window")
  2473. Text(0.5, 1.0, 'Frequency response of Blackman window')
  2474. >>> plt.ylabel("Magnitude [dB]")
  2475. Text(0, 0.5, 'Magnitude [dB]')
  2476. >>> plt.xlabel("Normalized frequency [cycles per sample]")
  2477. Text(0.5, 0, 'Normalized frequency [cycles per sample]')
  2478. >>> _ = plt.axis('tight')
  2479. >>> plt.show()
  2480. """
  2481. # Ensures at least float64 via 0.0. M should be an integer, but conversion
  2482. # to double is safe for a range.
  2483. values = np.array([0.0, M])
  2484. M = values[1]
  2485. if M < 1:
  2486. return array([], dtype=values.dtype)
  2487. if M == 1:
  2488. return ones(1, dtype=values.dtype)
  2489. n = arange(1-M, M, 2)
  2490. return 0.42 + 0.5*cos(pi*n/(M-1)) + 0.08*cos(2.0*pi*n/(M-1))
  2491. @set_module('numpy')
  2492. def bartlett(M):
  2493. """
  2494. Return the Bartlett window.
  2495. The Bartlett window is very similar to a triangular window, except
  2496. that the end points are at zero. It is often used in signal
  2497. processing for tapering a signal, without generating too much
  2498. ripple in the frequency domain.
  2499. Parameters
  2500. ----------
  2501. M : int
  2502. Number of points in the output window. If zero or less, an
  2503. empty array is returned.
  2504. Returns
  2505. -------
  2506. out : array
  2507. The triangular window, with the maximum value normalized to one
  2508. (the value one appears only if the number of samples is odd), with
  2509. the first and last samples equal to zero.
  2510. See Also
  2511. --------
  2512. blackman, hamming, hanning, kaiser
  2513. Notes
  2514. -----
  2515. The Bartlett window is defined as
  2516. .. math:: w(n) = \\frac{2}{M-1} \\left(
  2517. \\frac{M-1}{2} - \\left|n - \\frac{M-1}{2}\\right|
  2518. \\right)
  2519. Most references to the Bartlett window come from the signal processing
  2520. literature, where it is used as one of many windowing functions for
  2521. smoothing values. Note that convolution with this window produces linear
  2522. interpolation. It is also known as an apodization (which means "removing
  2523. the foot", i.e. smoothing discontinuities at the beginning and end of the
  2524. sampled signal) or tapering function. The Fourier transform of the
  2525. Bartlett window is the product of two sinc functions. Note the excellent
  2526. discussion in Kanasewich [2]_.
  2527. References
  2528. ----------
  2529. .. [1] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra",
  2530. Biometrika 37, 1-16, 1950.
  2531. .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
  2532. The University of Alberta Press, 1975, pp. 109-110.
  2533. .. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal
  2534. Processing", Prentice-Hall, 1999, pp. 468-471.
  2535. .. [4] Wikipedia, "Window function",
  2536. https://en.wikipedia.org/wiki/Window_function
  2537. .. [5] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
  2538. "Numerical Recipes", Cambridge University Press, 1986, page 429.
  2539. Examples
  2540. --------
  2541. >>> import matplotlib.pyplot as plt
  2542. >>> np.bartlett(12)
  2543. array([ 0. , 0.18181818, 0.36363636, 0.54545455, 0.72727273, # may vary
  2544. 0.90909091, 0.90909091, 0.72727273, 0.54545455, 0.36363636,
  2545. 0.18181818, 0. ])
  2546. Plot the window and its frequency response (requires SciPy and matplotlib):
  2547. >>> from numpy.fft import fft, fftshift
  2548. >>> window = np.bartlett(51)
  2549. >>> plt.plot(window)
  2550. [<matplotlib.lines.Line2D object at 0x...>]
  2551. >>> plt.title("Bartlett window")
  2552. Text(0.5, 1.0, 'Bartlett window')
  2553. >>> plt.ylabel("Amplitude")
  2554. Text(0, 0.5, 'Amplitude')
  2555. >>> plt.xlabel("Sample")
  2556. Text(0.5, 0, 'Sample')
  2557. >>> plt.show()
  2558. >>> plt.figure()
  2559. <Figure size 640x480 with 0 Axes>
  2560. >>> A = fft(window, 2048) / 25.5
  2561. >>> mag = np.abs(fftshift(A))
  2562. >>> freq = np.linspace(-0.5, 0.5, len(A))
  2563. >>> with np.errstate(divide='ignore', invalid='ignore'):
  2564. ... response = 20 * np.log10(mag)
  2565. ...
  2566. >>> response = np.clip(response, -100, 100)
  2567. >>> plt.plot(freq, response)
  2568. [<matplotlib.lines.Line2D object at 0x...>]
  2569. >>> plt.title("Frequency response of Bartlett window")
  2570. Text(0.5, 1.0, 'Frequency response of Bartlett window')
  2571. >>> plt.ylabel("Magnitude [dB]")
  2572. Text(0, 0.5, 'Magnitude [dB]')
  2573. >>> plt.xlabel("Normalized frequency [cycles per sample]")
  2574. Text(0.5, 0, 'Normalized frequency [cycles per sample]')
  2575. >>> _ = plt.axis('tight')
  2576. >>> plt.show()
  2577. """
  2578. # Ensures at least float64 via 0.0. M should be an integer, but conversion
  2579. # to double is safe for a range.
  2580. values = np.array([0.0, M])
  2581. M = values[1]
  2582. if M < 1:
  2583. return array([], dtype=values.dtype)
  2584. if M == 1:
  2585. return ones(1, dtype=values.dtype)
  2586. n = arange(1-M, M, 2)
  2587. return where(less_equal(n, 0), 1 + n/(M-1), 1 - n/(M-1))
  2588. @set_module('numpy')
  2589. def hanning(M):
  2590. """
  2591. Return the Hanning window.
  2592. The Hanning window is a taper formed by using a weighted cosine.
  2593. Parameters
  2594. ----------
  2595. M : int
  2596. Number of points in the output window. If zero or less, an
  2597. empty array is returned.
  2598. Returns
  2599. -------
  2600. out : ndarray, shape(M,)
  2601. The window, with the maximum value normalized to one (the value
  2602. one appears only if `M` is odd).
  2603. See Also
  2604. --------
  2605. bartlett, blackman, hamming, kaiser
  2606. Notes
  2607. -----
  2608. The Hanning window is defined as
  2609. .. math:: w(n) = 0.5 - 0.5\\cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
  2610. \\qquad 0 \\leq n \\leq M-1
  2611. The Hanning was named for Julius von Hann, an Austrian meteorologist.
  2612. It is also known as the Cosine Bell. Some authors prefer that it be
  2613. called a Hann window, to help avoid confusion with the very similar
  2614. Hamming window.
  2615. Most references to the Hanning window come from the signal processing
  2616. literature, where it is used as one of many windowing functions for
  2617. smoothing values. It is also known as an apodization (which means
  2618. "removing the foot", i.e. smoothing discontinuities at the beginning
  2619. and end of the sampled signal) or tapering function.
  2620. References
  2621. ----------
  2622. .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
  2623. spectra, Dover Publications, New York.
  2624. .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics",
  2625. The University of Alberta Press, 1975, pp. 106-108.
  2626. .. [3] Wikipedia, "Window function",
  2627. https://en.wikipedia.org/wiki/Window_function
  2628. .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
  2629. "Numerical Recipes", Cambridge University Press, 1986, page 425.
  2630. Examples
  2631. --------
  2632. >>> np.hanning(12)
  2633. array([0. , 0.07937323, 0.29229249, 0.57115742, 0.82743037,
  2634. 0.97974649, 0.97974649, 0.82743037, 0.57115742, 0.29229249,
  2635. 0.07937323, 0. ])
  2636. Plot the window and its frequency response:
  2637. >>> import matplotlib.pyplot as plt
  2638. >>> from numpy.fft import fft, fftshift
  2639. >>> window = np.hanning(51)
  2640. >>> plt.plot(window)
  2641. [<matplotlib.lines.Line2D object at 0x...>]
  2642. >>> plt.title("Hann window")
  2643. Text(0.5, 1.0, 'Hann window')
  2644. >>> plt.ylabel("Amplitude")
  2645. Text(0, 0.5, 'Amplitude')
  2646. >>> plt.xlabel("Sample")
  2647. Text(0.5, 0, 'Sample')
  2648. >>> plt.show()
  2649. >>> plt.figure()
  2650. <Figure size 640x480 with 0 Axes>
  2651. >>> A = fft(window, 2048) / 25.5
  2652. >>> mag = np.abs(fftshift(A))
  2653. >>> freq = np.linspace(-0.5, 0.5, len(A))
  2654. >>> with np.errstate(divide='ignore', invalid='ignore'):
  2655. ... response = 20 * np.log10(mag)
  2656. ...
  2657. >>> response = np.clip(response, -100, 100)
  2658. >>> plt.plot(freq, response)
  2659. [<matplotlib.lines.Line2D object at 0x...>]
  2660. >>> plt.title("Frequency response of the Hann window")
  2661. Text(0.5, 1.0, 'Frequency response of the Hann window')
  2662. >>> plt.ylabel("Magnitude [dB]")
  2663. Text(0, 0.5, 'Magnitude [dB]')
  2664. >>> plt.xlabel("Normalized frequency [cycles per sample]")
  2665. Text(0.5, 0, 'Normalized frequency [cycles per sample]')
  2666. >>> plt.axis('tight')
  2667. ...
  2668. >>> plt.show()
  2669. """
  2670. # Ensures at least float64 via 0.0. M should be an integer, but conversion
  2671. # to double is safe for a range.
  2672. values = np.array([0.0, M])
  2673. M = values[1]
  2674. if M < 1:
  2675. return array([], dtype=values.dtype)
  2676. if M == 1:
  2677. return ones(1, dtype=values.dtype)
  2678. n = arange(1-M, M, 2)
  2679. return 0.5 + 0.5*cos(pi*n/(M-1))
  2680. @set_module('numpy')
  2681. def hamming(M):
  2682. """
  2683. Return the Hamming window.
  2684. The Hamming window is a taper formed by using a weighted cosine.
  2685. Parameters
  2686. ----------
  2687. M : int
  2688. Number of points in the output window. If zero or less, an
  2689. empty array is returned.
  2690. Returns
  2691. -------
  2692. out : ndarray
  2693. The window, with the maximum value normalized to one (the value
  2694. one appears only if the number of samples is odd).
  2695. See Also
  2696. --------
  2697. bartlett, blackman, hanning, kaiser
  2698. Notes
  2699. -----
  2700. The Hamming window is defined as
  2701. .. math:: w(n) = 0.54 - 0.46\\cos\\left(\\frac{2\\pi{n}}{M-1}\\right)
  2702. \\qquad 0 \\leq n \\leq M-1
  2703. The Hamming was named for R. W. Hamming, an associate of J. W. Tukey
  2704. and is described in Blackman and Tukey. It was recommended for
  2705. smoothing the truncated autocovariance function in the time domain.
  2706. Most references to the Hamming window come from the signal processing
  2707. literature, where it is used as one of many windowing functions for
  2708. smoothing values. It is also known as an apodization (which means
  2709. "removing the foot", i.e. smoothing discontinuities at the beginning
  2710. and end of the sampled signal) or tapering function.
  2711. References
  2712. ----------
  2713. .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power
  2714. spectra, Dover Publications, New York.
  2715. .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
  2716. University of Alberta Press, 1975, pp. 109-110.
  2717. .. [3] Wikipedia, "Window function",
  2718. https://en.wikipedia.org/wiki/Window_function
  2719. .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling,
  2720. "Numerical Recipes", Cambridge University Press, 1986, page 425.
  2721. Examples
  2722. --------
  2723. >>> np.hamming(12)
  2724. array([ 0.08 , 0.15302337, 0.34890909, 0.60546483, 0.84123594, # may vary
  2725. 0.98136677, 0.98136677, 0.84123594, 0.60546483, 0.34890909,
  2726. 0.15302337, 0.08 ])
  2727. Plot the window and the frequency response:
  2728. >>> import matplotlib.pyplot as plt
  2729. >>> from numpy.fft import fft, fftshift
  2730. >>> window = np.hamming(51)
  2731. >>> plt.plot(window)
  2732. [<matplotlib.lines.Line2D object at 0x...>]
  2733. >>> plt.title("Hamming window")
  2734. Text(0.5, 1.0, 'Hamming window')
  2735. >>> plt.ylabel("Amplitude")
  2736. Text(0, 0.5, 'Amplitude')
  2737. >>> plt.xlabel("Sample")
  2738. Text(0.5, 0, 'Sample')
  2739. >>> plt.show()
  2740. >>> plt.figure()
  2741. <Figure size 640x480 with 0 Axes>
  2742. >>> A = fft(window, 2048) / 25.5
  2743. >>> mag = np.abs(fftshift(A))
  2744. >>> freq = np.linspace(-0.5, 0.5, len(A))
  2745. >>> response = 20 * np.log10(mag)
  2746. >>> response = np.clip(response, -100, 100)
  2747. >>> plt.plot(freq, response)
  2748. [<matplotlib.lines.Line2D object at 0x...>]
  2749. >>> plt.title("Frequency response of Hamming window")
  2750. Text(0.5, 1.0, 'Frequency response of Hamming window')
  2751. >>> plt.ylabel("Magnitude [dB]")
  2752. Text(0, 0.5, 'Magnitude [dB]')
  2753. >>> plt.xlabel("Normalized frequency [cycles per sample]")
  2754. Text(0.5, 0, 'Normalized frequency [cycles per sample]')
  2755. >>> plt.axis('tight')
  2756. ...
  2757. >>> plt.show()
  2758. """
  2759. # Ensures at least float64 via 0.0. M should be an integer, but conversion
  2760. # to double is safe for a range.
  2761. values = np.array([0.0, M])
  2762. M = values[1]
  2763. if M < 1:
  2764. return array([], dtype=values.dtype)
  2765. if M == 1:
  2766. return ones(1, dtype=values.dtype)
  2767. n = arange(1-M, M, 2)
  2768. return 0.54 + 0.46*cos(pi*n/(M-1))
  2769. ## Code from cephes for i0
  2770. _i0A = [
  2771. -4.41534164647933937950E-18,
  2772. 3.33079451882223809783E-17,
  2773. -2.43127984654795469359E-16,
  2774. 1.71539128555513303061E-15,
  2775. -1.16853328779934516808E-14,
  2776. 7.67618549860493561688E-14,
  2777. -4.85644678311192946090E-13,
  2778. 2.95505266312963983461E-12,
  2779. -1.72682629144155570723E-11,
  2780. 9.67580903537323691224E-11,
  2781. -5.18979560163526290666E-10,
  2782. 2.65982372468238665035E-9,
  2783. -1.30002500998624804212E-8,
  2784. 6.04699502254191894932E-8,
  2785. -2.67079385394061173391E-7,
  2786. 1.11738753912010371815E-6,
  2787. -4.41673835845875056359E-6,
  2788. 1.64484480707288970893E-5,
  2789. -5.75419501008210370398E-5,
  2790. 1.88502885095841655729E-4,
  2791. -5.76375574538582365885E-4,
  2792. 1.63947561694133579842E-3,
  2793. -4.32430999505057594430E-3,
  2794. 1.05464603945949983183E-2,
  2795. -2.37374148058994688156E-2,
  2796. 4.93052842396707084878E-2,
  2797. -9.49010970480476444210E-2,
  2798. 1.71620901522208775349E-1,
  2799. -3.04682672343198398683E-1,
  2800. 6.76795274409476084995E-1
  2801. ]
  2802. _i0B = [
  2803. -7.23318048787475395456E-18,
  2804. -4.83050448594418207126E-18,
  2805. 4.46562142029675999901E-17,
  2806. 3.46122286769746109310E-17,
  2807. -2.82762398051658348494E-16,
  2808. -3.42548561967721913462E-16,
  2809. 1.77256013305652638360E-15,
  2810. 3.81168066935262242075E-15,
  2811. -9.55484669882830764870E-15,
  2812. -4.15056934728722208663E-14,
  2813. 1.54008621752140982691E-14,
  2814. 3.85277838274214270114E-13,
  2815. 7.18012445138366623367E-13,
  2816. -1.79417853150680611778E-12,
  2817. -1.32158118404477131188E-11,
  2818. -3.14991652796324136454E-11,
  2819. 1.18891471078464383424E-11,
  2820. 4.94060238822496958910E-10,
  2821. 3.39623202570838634515E-9,
  2822. 2.26666899049817806459E-8,
  2823. 2.04891858946906374183E-7,
  2824. 2.89137052083475648297E-6,
  2825. 6.88975834691682398426E-5,
  2826. 3.36911647825569408990E-3,
  2827. 8.04490411014108831608E-1
  2828. ]
  2829. def _chbevl(x, vals):
  2830. b0 = vals[0]
  2831. b1 = 0.0
  2832. for i in range(1, len(vals)):
  2833. b2 = b1
  2834. b1 = b0
  2835. b0 = x*b1 - b2 + vals[i]
  2836. return 0.5*(b0 - b2)
  2837. def _i0_1(x):
  2838. return exp(x) * _chbevl(x/2.0-2, _i0A)
  2839. def _i0_2(x):
  2840. return exp(x) * _chbevl(32.0/x - 2.0, _i0B) / sqrt(x)
  2841. def _i0_dispatcher(x):
  2842. return (x,)
  2843. @array_function_dispatch(_i0_dispatcher)
  2844. def i0(x):
  2845. """
  2846. Modified Bessel function of the first kind, order 0.
  2847. Usually denoted :math:`I_0`.
  2848. Parameters
  2849. ----------
  2850. x : array_like of float
  2851. Argument of the Bessel function.
  2852. Returns
  2853. -------
  2854. out : ndarray, shape = x.shape, dtype = float
  2855. The modified Bessel function evaluated at each of the elements of `x`.
  2856. See Also
  2857. --------
  2858. scipy.special.i0, scipy.special.iv, scipy.special.ive
  2859. Notes
  2860. -----
  2861. The scipy implementation is recommended over this function: it is a
  2862. proper ufunc written in C, and more than an order of magnitude faster.
  2863. We use the algorithm published by Clenshaw [1]_ and referenced by
  2864. Abramowitz and Stegun [2]_, for which the function domain is
  2865. partitioned into the two intervals [0,8] and (8,inf), and Chebyshev
  2866. polynomial expansions are employed in each interval. Relative error on
  2867. the domain [0,30] using IEEE arithmetic is documented [3]_ as having a
  2868. peak of 5.8e-16 with an rms of 1.4e-16 (n = 30000).
  2869. References
  2870. ----------
  2871. .. [1] C. W. Clenshaw, "Chebyshev series for mathematical functions", in
  2872. *National Physical Laboratory Mathematical Tables*, vol. 5, London:
  2873. Her Majesty's Stationery Office, 1962.
  2874. .. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical
  2875. Functions*, 10th printing, New York: Dover, 1964, pp. 379.
  2876. https://personal.math.ubc.ca/~cbm/aands/page_379.htm
  2877. .. [3] https://metacpan.org/pod/distribution/Math-Cephes/lib/Math/Cephes.pod#i0:-Modified-Bessel-function-of-order-zero
  2878. Examples
  2879. --------
  2880. >>> np.i0(0.)
  2881. array(1.0)
  2882. >>> np.i0([0, 1, 2, 3])
  2883. array([1. , 1.26606588, 2.2795853 , 4.88079259])
  2884. """
  2885. x = np.asanyarray(x)
  2886. if x.dtype.kind == 'c':
  2887. raise TypeError("i0 not supported for complex values")
  2888. if x.dtype.kind != 'f':
  2889. x = x.astype(float)
  2890. x = np.abs(x)
  2891. return piecewise(x, [x <= 8.0], [_i0_1, _i0_2])
  2892. ## End of cephes code for i0
  2893. @set_module('numpy')
  2894. def kaiser(M, beta):
  2895. """
  2896. Return the Kaiser window.
  2897. The Kaiser window is a taper formed by using a Bessel function.
  2898. Parameters
  2899. ----------
  2900. M : int
  2901. Number of points in the output window. If zero or less, an
  2902. empty array is returned.
  2903. beta : float
  2904. Shape parameter for window.
  2905. Returns
  2906. -------
  2907. out : array
  2908. The window, with the maximum value normalized to one (the value
  2909. one appears only if the number of samples is odd).
  2910. See Also
  2911. --------
  2912. bartlett, blackman, hamming, hanning
  2913. Notes
  2914. -----
  2915. The Kaiser window is defined as
  2916. .. math:: w(n) = I_0\\left( \\beta \\sqrt{1-\\frac{4n^2}{(M-1)^2}}
  2917. \\right)/I_0(\\beta)
  2918. with
  2919. .. math:: \\quad -\\frac{M-1}{2} \\leq n \\leq \\frac{M-1}{2},
  2920. where :math:`I_0` is the modified zeroth-order Bessel function.
  2921. The Kaiser was named for Jim Kaiser, who discovered a simple
  2922. approximation to the DPSS window based on Bessel functions. The Kaiser
  2923. window is a very good approximation to the Digital Prolate Spheroidal
  2924. Sequence, or Slepian window, which is the transform which maximizes the
  2925. energy in the main lobe of the window relative to total energy.
  2926. The Kaiser can approximate many other windows by varying the beta
  2927. parameter.
  2928. ==== =======================
  2929. beta Window shape
  2930. ==== =======================
  2931. 0 Rectangular
  2932. 5 Similar to a Hamming
  2933. 6 Similar to a Hanning
  2934. 8.6 Similar to a Blackman
  2935. ==== =======================
  2936. A beta value of 14 is probably a good starting point. Note that as beta
  2937. gets large, the window narrows, and so the number of samples needs to be
  2938. large enough to sample the increasingly narrow spike, otherwise NaNs will
  2939. get returned.
  2940. Most references to the Kaiser window come from the signal processing
  2941. literature, where it is used as one of many windowing functions for
  2942. smoothing values. It is also known as an apodization (which means
  2943. "removing the foot", i.e. smoothing discontinuities at the beginning
  2944. and end of the sampled signal) or tapering function.
  2945. References
  2946. ----------
  2947. .. [1] J. F. Kaiser, "Digital Filters" - Ch 7 in "Systems analysis by
  2948. digital computer", Editors: F.F. Kuo and J.F. Kaiser, p 218-285.
  2949. John Wiley and Sons, New York, (1966).
  2950. .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The
  2951. University of Alberta Press, 1975, pp. 177-178.
  2952. .. [3] Wikipedia, "Window function",
  2953. https://en.wikipedia.org/wiki/Window_function
  2954. Examples
  2955. --------
  2956. >>> import matplotlib.pyplot as plt
  2957. >>> np.kaiser(12, 14)
  2958. array([7.72686684e-06, 3.46009194e-03, 4.65200189e-02, # may vary
  2959. 2.29737120e-01, 5.99885316e-01, 9.45674898e-01,
  2960. 9.45674898e-01, 5.99885316e-01, 2.29737120e-01,
  2961. 4.65200189e-02, 3.46009194e-03, 7.72686684e-06])
  2962. Plot the window and the frequency response:
  2963. >>> from numpy.fft import fft, fftshift
  2964. >>> window = np.kaiser(51, 14)
  2965. >>> plt.plot(window)
  2966. [<matplotlib.lines.Line2D object at 0x...>]
  2967. >>> plt.title("Kaiser window")
  2968. Text(0.5, 1.0, 'Kaiser window')
  2969. >>> plt.ylabel("Amplitude")
  2970. Text(0, 0.5, 'Amplitude')
  2971. >>> plt.xlabel("Sample")
  2972. Text(0.5, 0, 'Sample')
  2973. >>> plt.show()
  2974. >>> plt.figure()
  2975. <Figure size 640x480 with 0 Axes>
  2976. >>> A = fft(window, 2048) / 25.5
  2977. >>> mag = np.abs(fftshift(A))
  2978. >>> freq = np.linspace(-0.5, 0.5, len(A))
  2979. >>> response = 20 * np.log10(mag)
  2980. >>> response = np.clip(response, -100, 100)
  2981. >>> plt.plot(freq, response)
  2982. [<matplotlib.lines.Line2D object at 0x...>]
  2983. >>> plt.title("Frequency response of Kaiser window")
  2984. Text(0.5, 1.0, 'Frequency response of Kaiser window')
  2985. >>> plt.ylabel("Magnitude [dB]")
  2986. Text(0, 0.5, 'Magnitude [dB]')
  2987. >>> plt.xlabel("Normalized frequency [cycles per sample]")
  2988. Text(0.5, 0, 'Normalized frequency [cycles per sample]')
  2989. >>> plt.axis('tight')
  2990. (-0.5, 0.5, -100.0, ...) # may vary
  2991. >>> plt.show()
  2992. """
  2993. # Ensures at least float64 via 0.0. M should be an integer, but conversion
  2994. # to double is safe for a range. (Simplified result_type with 0.0
  2995. # strongly typed. result-type is not/less order sensitive, but that mainly
  2996. # matters for integers anyway.)
  2997. values = np.array([0.0, M, beta])
  2998. M = values[1]
  2999. beta = values[2]
  3000. if M == 1:
  3001. return np.ones(1, dtype=values.dtype)
  3002. n = arange(0, M)
  3003. alpha = (M-1)/2.0
  3004. return i0(beta * sqrt(1-((n-alpha)/alpha)**2.0))/i0(beta)
  3005. def _sinc_dispatcher(x):
  3006. return (x,)
  3007. @array_function_dispatch(_sinc_dispatcher)
  3008. def sinc(x):
  3009. r"""
  3010. Return the normalized sinc function.
  3011. The sinc function is equal to :math:`\sin(\pi x)/(\pi x)` for any argument
  3012. :math:`x\ne 0`. ``sinc(0)`` takes the limit value 1, making ``sinc`` not
  3013. only everywhere continuous but also infinitely differentiable.
  3014. .. note::
  3015. Note the normalization factor of ``pi`` used in the definition.
  3016. This is the most commonly used definition in signal processing.
  3017. Use ``sinc(x / np.pi)`` to obtain the unnormalized sinc function
  3018. :math:`\sin(x)/x` that is more common in mathematics.
  3019. Parameters
  3020. ----------
  3021. x : ndarray
  3022. Array (possibly multi-dimensional) of values for which to calculate
  3023. ``sinc(x)``.
  3024. Returns
  3025. -------
  3026. out : ndarray
  3027. ``sinc(x)``, which has the same shape as the input.
  3028. Notes
  3029. -----
  3030. The name sinc is short for "sine cardinal" or "sinus cardinalis".
  3031. The sinc function is used in various signal processing applications,
  3032. including in anti-aliasing, in the construction of a Lanczos resampling
  3033. filter, and in interpolation.
  3034. For bandlimited interpolation of discrete-time signals, the ideal
  3035. interpolation kernel is proportional to the sinc function.
  3036. References
  3037. ----------
  3038. .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
  3039. Resource. http://mathworld.wolfram.com/SincFunction.html
  3040. .. [2] Wikipedia, "Sinc function",
  3041. https://en.wikipedia.org/wiki/Sinc_function
  3042. Examples
  3043. --------
  3044. >>> import matplotlib.pyplot as plt
  3045. >>> x = np.linspace(-4, 4, 41)
  3046. >>> np.sinc(x)
  3047. array([-3.89804309e-17, -4.92362781e-02, -8.40918587e-02, # may vary
  3048. -8.90384387e-02, -5.84680802e-02, 3.89804309e-17,
  3049. 6.68206631e-02, 1.16434881e-01, 1.26137788e-01,
  3050. 8.50444803e-02, -3.89804309e-17, -1.03943254e-01,
  3051. -1.89206682e-01, -2.16236208e-01, -1.55914881e-01,
  3052. 3.89804309e-17, 2.33872321e-01, 5.04551152e-01,
  3053. 7.56826729e-01, 9.35489284e-01, 1.00000000e+00,
  3054. 9.35489284e-01, 7.56826729e-01, 5.04551152e-01,
  3055. 2.33872321e-01, 3.89804309e-17, -1.55914881e-01,
  3056. -2.16236208e-01, -1.89206682e-01, -1.03943254e-01,
  3057. -3.89804309e-17, 8.50444803e-02, 1.26137788e-01,
  3058. 1.16434881e-01, 6.68206631e-02, 3.89804309e-17,
  3059. -5.84680802e-02, -8.90384387e-02, -8.40918587e-02,
  3060. -4.92362781e-02, -3.89804309e-17])
  3061. >>> plt.plot(x, np.sinc(x))
  3062. [<matplotlib.lines.Line2D object at 0x...>]
  3063. >>> plt.title("Sinc Function")
  3064. Text(0.5, 1.0, 'Sinc Function')
  3065. >>> plt.ylabel("Amplitude")
  3066. Text(0, 0.5, 'Amplitude')
  3067. >>> plt.xlabel("X")
  3068. Text(0.5, 0, 'X')
  3069. >>> plt.show()
  3070. """
  3071. x = np.asanyarray(x)
  3072. y = pi * where(x == 0, 1.0e-20, x)
  3073. return sin(y)/y
  3074. def _msort_dispatcher(a):
  3075. return (a,)
  3076. @array_function_dispatch(_msort_dispatcher)
  3077. def msort(a):
  3078. """
  3079. Return a copy of an array sorted along the first axis.
  3080. .. deprecated:: 1.24
  3081. msort is deprecated, use ``np.sort(a, axis=0)`` instead.
  3082. Parameters
  3083. ----------
  3084. a : array_like
  3085. Array to be sorted.
  3086. Returns
  3087. -------
  3088. sorted_array : ndarray
  3089. Array of the same type and shape as `a`.
  3090. See Also
  3091. --------
  3092. sort
  3093. Notes
  3094. -----
  3095. ``np.msort(a)`` is equivalent to ``np.sort(a, axis=0)``.
  3096. Examples
  3097. --------
  3098. >>> a = np.array([[1, 4], [3, 1]])
  3099. >>> np.msort(a) # sort along the first axis
  3100. array([[1, 1],
  3101. [3, 4]])
  3102. """
  3103. # 2022-10-20 1.24
  3104. warnings.warn(
  3105. "msort is deprecated, use np.sort(a, axis=0) instead",
  3106. DeprecationWarning,
  3107. stacklevel=2,
  3108. )
  3109. b = array(a, subok=True, copy=True)
  3110. b.sort(0)
  3111. return b
  3112. def _ureduce(a, func, keepdims=False, **kwargs):
  3113. """
  3114. Internal Function.
  3115. Call `func` with `a` as first argument swapping the axes to use extended
  3116. axis on functions that don't support it natively.
  3117. Returns result and a.shape with axis dims set to 1.
  3118. Parameters
  3119. ----------
  3120. a : array_like
  3121. Input array or object that can be converted to an array.
  3122. func : callable
  3123. Reduction function capable of receiving a single axis argument.
  3124. It is called with `a` as first argument followed by `kwargs`.
  3125. kwargs : keyword arguments
  3126. additional keyword arguments to pass to `func`.
  3127. Returns
  3128. -------
  3129. result : tuple
  3130. Result of func(a, **kwargs) and a.shape with axis dims set to 1
  3131. which can be used to reshape the result to the same shape a ufunc with
  3132. keepdims=True would produce.
  3133. """
  3134. a = np.asanyarray(a)
  3135. axis = kwargs.get('axis', None)
  3136. out = kwargs.get('out', None)
  3137. if keepdims is np._NoValue:
  3138. keepdims = False
  3139. nd = a.ndim
  3140. if axis is not None:
  3141. axis = _nx.normalize_axis_tuple(axis, nd)
  3142. if keepdims:
  3143. if out is not None:
  3144. index_out = tuple(
  3145. 0 if i in axis else slice(None) for i in range(nd))
  3146. kwargs['out'] = out[(Ellipsis, ) + index_out]
  3147. if len(axis) == 1:
  3148. kwargs['axis'] = axis[0]
  3149. else:
  3150. keep = set(range(nd)) - set(axis)
  3151. nkeep = len(keep)
  3152. # swap axis that should not be reduced to front
  3153. for i, s in enumerate(sorted(keep)):
  3154. a = a.swapaxes(i, s)
  3155. # merge reduced axis
  3156. a = a.reshape(a.shape[:nkeep] + (-1,))
  3157. kwargs['axis'] = -1
  3158. else:
  3159. if keepdims:
  3160. if out is not None:
  3161. index_out = (0, ) * nd
  3162. kwargs['out'] = out[(Ellipsis, ) + index_out]
  3163. r = func(a, **kwargs)
  3164. if out is not None:
  3165. return out
  3166. if keepdims:
  3167. if axis is None:
  3168. index_r = (np.newaxis, ) * nd
  3169. else:
  3170. index_r = tuple(
  3171. np.newaxis if i in axis else slice(None)
  3172. for i in range(nd))
  3173. r = r[(Ellipsis, ) + index_r]
  3174. return r
  3175. def _median_dispatcher(
  3176. a, axis=None, out=None, overwrite_input=None, keepdims=None):
  3177. return (a, out)
  3178. @array_function_dispatch(_median_dispatcher)
  3179. def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
  3180. """
  3181. Compute the median along the specified axis.
  3182. Returns the median of the array elements.
  3183. Parameters
  3184. ----------
  3185. a : array_like
  3186. Input array or object that can be converted to an array.
  3187. axis : {int, sequence of int, None}, optional
  3188. Axis or axes along which the medians are computed. The default
  3189. is to compute the median along a flattened version of the array.
  3190. A sequence of axes is supported since version 1.9.0.
  3191. out : ndarray, optional
  3192. Alternative output array in which to place the result. It must
  3193. have the same shape and buffer length as the expected output,
  3194. but the type (of the output) will be cast if necessary.
  3195. overwrite_input : bool, optional
  3196. If True, then allow use of memory of input array `a` for
  3197. calculations. The input array will be modified by the call to
  3198. `median`. This will save memory when you do not need to preserve
  3199. the contents of the input array. Treat the input as undefined,
  3200. but it will probably be fully or partially sorted. Default is
  3201. False. If `overwrite_input` is ``True`` and `a` is not already an
  3202. `ndarray`, an error will be raised.
  3203. keepdims : bool, optional
  3204. If this is set to True, the axes which are reduced are left
  3205. in the result as dimensions with size one. With this option,
  3206. the result will broadcast correctly against the original `arr`.
  3207. .. versionadded:: 1.9.0
  3208. Returns
  3209. -------
  3210. median : ndarray
  3211. A new array holding the result. If the input contains integers
  3212. or floats smaller than ``float64``, then the output data-type is
  3213. ``np.float64``. Otherwise, the data-type of the output is the
  3214. same as that of the input. If `out` is specified, that array is
  3215. returned instead.
  3216. See Also
  3217. --------
  3218. mean, percentile
  3219. Notes
  3220. -----
  3221. Given a vector ``V`` of length ``N``, the median of ``V`` is the
  3222. middle value of a sorted copy of ``V``, ``V_sorted`` - i
  3223. e., ``V_sorted[(N-1)/2]``, when ``N`` is odd, and the average of the
  3224. two middle values of ``V_sorted`` when ``N`` is even.
  3225. Examples
  3226. --------
  3227. >>> a = np.array([[10, 7, 4], [3, 2, 1]])
  3228. >>> a
  3229. array([[10, 7, 4],
  3230. [ 3, 2, 1]])
  3231. >>> np.median(a)
  3232. 3.5
  3233. >>> np.median(a, axis=0)
  3234. array([6.5, 4.5, 2.5])
  3235. >>> np.median(a, axis=1)
  3236. array([7., 2.])
  3237. >>> m = np.median(a, axis=0)
  3238. >>> out = np.zeros_like(m)
  3239. >>> np.median(a, axis=0, out=m)
  3240. array([6.5, 4.5, 2.5])
  3241. >>> m
  3242. array([6.5, 4.5, 2.5])
  3243. >>> b = a.copy()
  3244. >>> np.median(b, axis=1, overwrite_input=True)
  3245. array([7., 2.])
  3246. >>> assert not np.all(a==b)
  3247. >>> b = a.copy()
  3248. >>> np.median(b, axis=None, overwrite_input=True)
  3249. 3.5
  3250. >>> assert not np.all(a==b)
  3251. """
  3252. return _ureduce(a, func=_median, keepdims=keepdims, axis=axis, out=out,
  3253. overwrite_input=overwrite_input)
  3254. def _median(a, axis=None, out=None, overwrite_input=False):
  3255. # can't be reasonably be implemented in terms of percentile as we have to
  3256. # call mean to not break astropy
  3257. a = np.asanyarray(a)
  3258. # Set the partition indexes
  3259. if axis is None:
  3260. sz = a.size
  3261. else:
  3262. sz = a.shape[axis]
  3263. if sz % 2 == 0:
  3264. szh = sz // 2
  3265. kth = [szh - 1, szh]
  3266. else:
  3267. kth = [(sz - 1) // 2]
  3268. # We have to check for NaNs (as of writing 'M' doesn't actually work).
  3269. supports_nans = np.issubdtype(a.dtype, np.inexact) or a.dtype.kind in 'Mm'
  3270. if supports_nans:
  3271. kth.append(-1)
  3272. if overwrite_input:
  3273. if axis is None:
  3274. part = a.ravel()
  3275. part.partition(kth)
  3276. else:
  3277. a.partition(kth, axis=axis)
  3278. part = a
  3279. else:
  3280. part = partition(a, kth, axis=axis)
  3281. if part.shape == ():
  3282. # make 0-D arrays work
  3283. return part.item()
  3284. if axis is None:
  3285. axis = 0
  3286. indexer = [slice(None)] * part.ndim
  3287. index = part.shape[axis] // 2
  3288. if part.shape[axis] % 2 == 1:
  3289. # index with slice to allow mean (below) to work
  3290. indexer[axis] = slice(index, index+1)
  3291. else:
  3292. indexer[axis] = slice(index-1, index+1)
  3293. indexer = tuple(indexer)
  3294. # Use mean in both odd and even case to coerce data type,
  3295. # using out array if needed.
  3296. rout = mean(part[indexer], axis=axis, out=out)
  3297. if supports_nans and sz > 0:
  3298. # If nans are possible, warn and replace by nans like mean would.
  3299. rout = np.lib.utils._median_nancheck(part, rout, axis)
  3300. return rout
  3301. def _percentile_dispatcher(a, q, axis=None, out=None, overwrite_input=None,
  3302. method=None, keepdims=None, *, interpolation=None):
  3303. return (a, q, out)
  3304. @array_function_dispatch(_percentile_dispatcher)
  3305. def percentile(a,
  3306. q,
  3307. axis=None,
  3308. out=None,
  3309. overwrite_input=False,
  3310. method="linear",
  3311. keepdims=False,
  3312. *,
  3313. interpolation=None):
  3314. """
  3315. Compute the q-th percentile of the data along the specified axis.
  3316. Returns the q-th percentile(s) of the array elements.
  3317. Parameters
  3318. ----------
  3319. a : array_like of real numbers
  3320. Input array or object that can be converted to an array.
  3321. q : array_like of float
  3322. Percentage or sequence of percentages for the percentiles to compute.
  3323. Values must be between 0 and 100 inclusive.
  3324. axis : {int, tuple of int, None}, optional
  3325. Axis or axes along which the percentiles are computed. The
  3326. default is to compute the percentile(s) along a flattened
  3327. version of the array.
  3328. .. versionchanged:: 1.9.0
  3329. A tuple of axes is supported
  3330. out : ndarray, optional
  3331. Alternative output array in which to place the result. It must
  3332. have the same shape and buffer length as the expected output,
  3333. but the type (of the output) will be cast if necessary.
  3334. overwrite_input : bool, optional
  3335. If True, then allow the input array `a` to be modified by intermediate
  3336. calculations, to save memory. In this case, the contents of the input
  3337. `a` after this function completes is undefined.
  3338. method : str, optional
  3339. This parameter specifies the method to use for estimating the
  3340. percentile. There are many different methods, some unique to NumPy.
  3341. See the notes for explanation. The options sorted by their R type
  3342. as summarized in the H&F paper [1]_ are:
  3343. 1. 'inverted_cdf'
  3344. 2. 'averaged_inverted_cdf'
  3345. 3. 'closest_observation'
  3346. 4. 'interpolated_inverted_cdf'
  3347. 5. 'hazen'
  3348. 6. 'weibull'
  3349. 7. 'linear' (default)
  3350. 8. 'median_unbiased'
  3351. 9. 'normal_unbiased'
  3352. The first three methods are discontinuous. NumPy further defines the
  3353. following discontinuous variations of the default 'linear' (7.) option:
  3354. * 'lower'
  3355. * 'higher',
  3356. * 'midpoint'
  3357. * 'nearest'
  3358. .. versionchanged:: 1.22.0
  3359. This argument was previously called "interpolation" and only
  3360. offered the "linear" default and last four options.
  3361. keepdims : bool, optional
  3362. If this is set to True, the axes which are reduced are left in
  3363. the result as dimensions with size one. With this option, the
  3364. result will broadcast correctly against the original array `a`.
  3365. .. versionadded:: 1.9.0
  3366. interpolation : str, optional
  3367. Deprecated name for the method keyword argument.
  3368. .. deprecated:: 1.22.0
  3369. Returns
  3370. -------
  3371. percentile : scalar or ndarray
  3372. If `q` is a single percentile and `axis=None`, then the result
  3373. is a scalar. If multiple percentiles are given, first axis of
  3374. the result corresponds to the percentiles. The other axes are
  3375. the axes that remain after the reduction of `a`. If the input
  3376. contains integers or floats smaller than ``float64``, the output
  3377. data-type is ``float64``. Otherwise, the output data-type is the
  3378. same as that of the input. If `out` is specified, that array is
  3379. returned instead.
  3380. See Also
  3381. --------
  3382. mean
  3383. median : equivalent to ``percentile(..., 50)``
  3384. nanpercentile
  3385. quantile : equivalent to percentile, except q in the range [0, 1].
  3386. Notes
  3387. -----
  3388. Given a vector ``V`` of length ``n``, the q-th percentile of ``V`` is
  3389. the value ``q/100`` of the way from the minimum to the maximum in a
  3390. sorted copy of ``V``. The values and distances of the two nearest
  3391. neighbors as well as the `method` parameter will determine the
  3392. percentile if the normalized ranking does not match the location of
  3393. ``q`` exactly. This function is the same as the median if ``q=50``, the
  3394. same as the minimum if ``q=0`` and the same as the maximum if
  3395. ``q=100``.
  3396. The optional `method` parameter specifies the method to use when the
  3397. desired percentile lies between two indexes ``i`` and ``j = i + 1``.
  3398. In that case, we first determine ``i + g``, a virtual index that lies
  3399. between ``i`` and ``j``, where ``i`` is the floor and ``g`` is the
  3400. fractional part of the index. The final result is, then, an interpolation
  3401. of ``a[i]`` and ``a[j]`` based on ``g``. During the computation of ``g``,
  3402. ``i`` and ``j`` are modified using correction constants ``alpha`` and
  3403. ``beta`` whose choices depend on the ``method`` used. Finally, note that
  3404. since Python uses 0-based indexing, the code subtracts another 1 from the
  3405. index internally.
  3406. The following formula determines the virtual index ``i + g``, the location
  3407. of the percentile in the sorted sample:
  3408. .. math::
  3409. i + g = (q / 100) * ( n - alpha - beta + 1 ) + alpha
  3410. The different methods then work as follows
  3411. inverted_cdf:
  3412. method 1 of H&F [1]_.
  3413. This method gives discontinuous results:
  3414. * if g > 0 ; then take j
  3415. * if g = 0 ; then take i
  3416. averaged_inverted_cdf:
  3417. method 2 of H&F [1]_.
  3418. This method give discontinuous results:
  3419. * if g > 0 ; then take j
  3420. * if g = 0 ; then average between bounds
  3421. closest_observation:
  3422. method 3 of H&F [1]_.
  3423. This method give discontinuous results:
  3424. * if g > 0 ; then take j
  3425. * if g = 0 and index is odd ; then take j
  3426. * if g = 0 and index is even ; then take i
  3427. interpolated_inverted_cdf:
  3428. method 4 of H&F [1]_.
  3429. This method give continuous results using:
  3430. * alpha = 0
  3431. * beta = 1
  3432. hazen:
  3433. method 5 of H&F [1]_.
  3434. This method give continuous results using:
  3435. * alpha = 1/2
  3436. * beta = 1/2
  3437. weibull:
  3438. method 6 of H&F [1]_.
  3439. This method give continuous results using:
  3440. * alpha = 0
  3441. * beta = 0
  3442. linear:
  3443. method 7 of H&F [1]_.
  3444. This method give continuous results using:
  3445. * alpha = 1
  3446. * beta = 1
  3447. median_unbiased:
  3448. method 8 of H&F [1]_.
  3449. This method is probably the best method if the sample
  3450. distribution function is unknown (see reference).
  3451. This method give continuous results using:
  3452. * alpha = 1/3
  3453. * beta = 1/3
  3454. normal_unbiased:
  3455. method 9 of H&F [1]_.
  3456. This method is probably the best method if the sample
  3457. distribution function is known to be normal.
  3458. This method give continuous results using:
  3459. * alpha = 3/8
  3460. * beta = 3/8
  3461. lower:
  3462. NumPy method kept for backwards compatibility.
  3463. Takes ``i`` as the interpolation point.
  3464. higher:
  3465. NumPy method kept for backwards compatibility.
  3466. Takes ``j`` as the interpolation point.
  3467. nearest:
  3468. NumPy method kept for backwards compatibility.
  3469. Takes ``i`` or ``j``, whichever is nearest.
  3470. midpoint:
  3471. NumPy method kept for backwards compatibility.
  3472. Uses ``(i + j) / 2``.
  3473. Examples
  3474. --------
  3475. >>> a = np.array([[10, 7, 4], [3, 2, 1]])
  3476. >>> a
  3477. array([[10, 7, 4],
  3478. [ 3, 2, 1]])
  3479. >>> np.percentile(a, 50)
  3480. 3.5
  3481. >>> np.percentile(a, 50, axis=0)
  3482. array([6.5, 4.5, 2.5])
  3483. >>> np.percentile(a, 50, axis=1)
  3484. array([7., 2.])
  3485. >>> np.percentile(a, 50, axis=1, keepdims=True)
  3486. array([[7.],
  3487. [2.]])
  3488. >>> m = np.percentile(a, 50, axis=0)
  3489. >>> out = np.zeros_like(m)
  3490. >>> np.percentile(a, 50, axis=0, out=out)
  3491. array([6.5, 4.5, 2.5])
  3492. >>> m
  3493. array([6.5, 4.5, 2.5])
  3494. >>> b = a.copy()
  3495. >>> np.percentile(b, 50, axis=1, overwrite_input=True)
  3496. array([7., 2.])
  3497. >>> assert not np.all(a == b)
  3498. The different methods can be visualized graphically:
  3499. .. plot::
  3500. import matplotlib.pyplot as plt
  3501. a = np.arange(4)
  3502. p = np.linspace(0, 100, 6001)
  3503. ax = plt.gca()
  3504. lines = [
  3505. ('linear', '-', 'C0'),
  3506. ('inverted_cdf', ':', 'C1'),
  3507. # Almost the same as `inverted_cdf`:
  3508. ('averaged_inverted_cdf', '-.', 'C1'),
  3509. ('closest_observation', ':', 'C2'),
  3510. ('interpolated_inverted_cdf', '--', 'C1'),
  3511. ('hazen', '--', 'C3'),
  3512. ('weibull', '-.', 'C4'),
  3513. ('median_unbiased', '--', 'C5'),
  3514. ('normal_unbiased', '-.', 'C6'),
  3515. ]
  3516. for method, style, color in lines:
  3517. ax.plot(
  3518. p, np.percentile(a, p, method=method),
  3519. label=method, linestyle=style, color=color)
  3520. ax.set(
  3521. title='Percentiles for different methods and data: ' + str(a),
  3522. xlabel='Percentile',
  3523. ylabel='Estimated percentile value',
  3524. yticks=a)
  3525. ax.legend(bbox_to_anchor=(1.03, 1))
  3526. plt.tight_layout()
  3527. plt.show()
  3528. References
  3529. ----------
  3530. .. [1] R. J. Hyndman and Y. Fan,
  3531. "Sample quantiles in statistical packages,"
  3532. The American Statistician, 50(4), pp. 361-365, 1996
  3533. """
  3534. if interpolation is not None:
  3535. method = _check_interpolation_as_method(
  3536. method, interpolation, "percentile")
  3537. a = np.asanyarray(a)
  3538. if a.dtype.kind == "c":
  3539. raise TypeError("a must be an array of real numbers")
  3540. q = np.true_divide(q, 100)
  3541. q = asanyarray(q) # undo any decay that the ufunc performed (see gh-13105)
  3542. if not _quantile_is_valid(q):
  3543. raise ValueError("Percentiles must be in the range [0, 100]")
  3544. return _quantile_unchecked(
  3545. a, q, axis, out, overwrite_input, method, keepdims)
  3546. def _quantile_dispatcher(a, q, axis=None, out=None, overwrite_input=None,
  3547. method=None, keepdims=None, *, interpolation=None):
  3548. return (a, q, out)
  3549. @array_function_dispatch(_quantile_dispatcher)
  3550. def quantile(a,
  3551. q,
  3552. axis=None,
  3553. out=None,
  3554. overwrite_input=False,
  3555. method="linear",
  3556. keepdims=False,
  3557. *,
  3558. interpolation=None):
  3559. """
  3560. Compute the q-th quantile of the data along the specified axis.
  3561. .. versionadded:: 1.15.0
  3562. Parameters
  3563. ----------
  3564. a : array_like of real numbers
  3565. Input array or object that can be converted to an array.
  3566. q : array_like of float
  3567. Probability or sequence of probabilities for the quantiles to compute.
  3568. Values must be between 0 and 1 inclusive.
  3569. axis : {int, tuple of int, None}, optional
  3570. Axis or axes along which the quantiles are computed. The default is
  3571. to compute the quantile(s) along a flattened version of the array.
  3572. out : ndarray, optional
  3573. Alternative output array in which to place the result. It must have
  3574. the same shape and buffer length as the expected output, but the
  3575. type (of the output) will be cast if necessary.
  3576. overwrite_input : bool, optional
  3577. If True, then allow the input array `a` to be modified by
  3578. intermediate calculations, to save memory. In this case, the
  3579. contents of the input `a` after this function completes is
  3580. undefined.
  3581. method : str, optional
  3582. This parameter specifies the method to use for estimating the
  3583. quantile. There are many different methods, some unique to NumPy.
  3584. See the notes for explanation. The options sorted by their R type
  3585. as summarized in the H&F paper [1]_ are:
  3586. 1. 'inverted_cdf'
  3587. 2. 'averaged_inverted_cdf'
  3588. 3. 'closest_observation'
  3589. 4. 'interpolated_inverted_cdf'
  3590. 5. 'hazen'
  3591. 6. 'weibull'
  3592. 7. 'linear' (default)
  3593. 8. 'median_unbiased'
  3594. 9. 'normal_unbiased'
  3595. The first three methods are discontinuous. NumPy further defines the
  3596. following discontinuous variations of the default 'linear' (7.) option:
  3597. * 'lower'
  3598. * 'higher',
  3599. * 'midpoint'
  3600. * 'nearest'
  3601. .. versionchanged:: 1.22.0
  3602. This argument was previously called "interpolation" and only
  3603. offered the "linear" default and last four options.
  3604. keepdims : bool, optional
  3605. If this is set to True, the axes which are reduced are left in
  3606. the result as dimensions with size one. With this option, the
  3607. result will broadcast correctly against the original array `a`.
  3608. interpolation : str, optional
  3609. Deprecated name for the method keyword argument.
  3610. .. deprecated:: 1.22.0
  3611. Returns
  3612. -------
  3613. quantile : scalar or ndarray
  3614. If `q` is a single probability and `axis=None`, then the result
  3615. is a scalar. If multiple probabilies levels are given, first axis of
  3616. the result corresponds to the quantiles. The other axes are
  3617. the axes that remain after the reduction of `a`. If the input
  3618. contains integers or floats smaller than ``float64``, the output
  3619. data-type is ``float64``. Otherwise, the output data-type is the
  3620. same as that of the input. If `out` is specified, that array is
  3621. returned instead.
  3622. See Also
  3623. --------
  3624. mean
  3625. percentile : equivalent to quantile, but with q in the range [0, 100].
  3626. median : equivalent to ``quantile(..., 0.5)``
  3627. nanquantile
  3628. Notes
  3629. -----
  3630. Given a vector ``V`` of length ``n``, the q-th quantile of ``V`` is
  3631. the value ``q`` of the way from the minimum to the maximum in a
  3632. sorted copy of ``V``. The values and distances of the two nearest
  3633. neighbors as well as the `method` parameter will determine the
  3634. quantile if the normalized ranking does not match the location of
  3635. ``q`` exactly. This function is the same as the median if ``q=0.5``, the
  3636. same as the minimum if ``q=0.0`` and the same as the maximum if
  3637. ``q=1.0``.
  3638. The optional `method` parameter specifies the method to use when the
  3639. desired quantile lies between two indexes ``i`` and ``j = i + 1``.
  3640. In that case, we first determine ``i + g``, a virtual index that lies
  3641. between ``i`` and ``j``, where ``i`` is the floor and ``g`` is the
  3642. fractional part of the index. The final result is, then, an interpolation
  3643. of ``a[i]`` and ``a[j]`` based on ``g``. During the computation of ``g``,
  3644. ``i`` and ``j`` are modified using correction constants ``alpha`` and
  3645. ``beta`` whose choices depend on the ``method`` used. Finally, note that
  3646. since Python uses 0-based indexing, the code subtracts another 1 from the
  3647. index internally.
  3648. The following formula determines the virtual index ``i + g``, the location
  3649. of the quantile in the sorted sample:
  3650. .. math::
  3651. i + g = q * ( n - alpha - beta + 1 ) + alpha
  3652. The different methods then work as follows
  3653. inverted_cdf:
  3654. method 1 of H&F [1]_.
  3655. This method gives discontinuous results:
  3656. * if g > 0 ; then take j
  3657. * if g = 0 ; then take i
  3658. averaged_inverted_cdf:
  3659. method 2 of H&F [1]_.
  3660. This method gives discontinuous results:
  3661. * if g > 0 ; then take j
  3662. * if g = 0 ; then average between bounds
  3663. closest_observation:
  3664. method 3 of H&F [1]_.
  3665. This method gives discontinuous results:
  3666. * if g > 0 ; then take j
  3667. * if g = 0 and index is odd ; then take j
  3668. * if g = 0 and index is even ; then take i
  3669. interpolated_inverted_cdf:
  3670. method 4 of H&F [1]_.
  3671. This method gives continuous results using:
  3672. * alpha = 0
  3673. * beta = 1
  3674. hazen:
  3675. method 5 of H&F [1]_.
  3676. This method gives continuous results using:
  3677. * alpha = 1/2
  3678. * beta = 1/2
  3679. weibull:
  3680. method 6 of H&F [1]_.
  3681. This method gives continuous results using:
  3682. * alpha = 0
  3683. * beta = 0
  3684. linear:
  3685. method 7 of H&F [1]_.
  3686. This method gives continuous results using:
  3687. * alpha = 1
  3688. * beta = 1
  3689. median_unbiased:
  3690. method 8 of H&F [1]_.
  3691. This method is probably the best method if the sample
  3692. distribution function is unknown (see reference).
  3693. This method gives continuous results using:
  3694. * alpha = 1/3
  3695. * beta = 1/3
  3696. normal_unbiased:
  3697. method 9 of H&F [1]_.
  3698. This method is probably the best method if the sample
  3699. distribution function is known to be normal.
  3700. This method gives continuous results using:
  3701. * alpha = 3/8
  3702. * beta = 3/8
  3703. lower:
  3704. NumPy method kept for backwards compatibility.
  3705. Takes ``i`` as the interpolation point.
  3706. higher:
  3707. NumPy method kept for backwards compatibility.
  3708. Takes ``j`` as the interpolation point.
  3709. nearest:
  3710. NumPy method kept for backwards compatibility.
  3711. Takes ``i`` or ``j``, whichever is nearest.
  3712. midpoint:
  3713. NumPy method kept for backwards compatibility.
  3714. Uses ``(i + j) / 2``.
  3715. Examples
  3716. --------
  3717. >>> a = np.array([[10, 7, 4], [3, 2, 1]])
  3718. >>> a
  3719. array([[10, 7, 4],
  3720. [ 3, 2, 1]])
  3721. >>> np.quantile(a, 0.5)
  3722. 3.5
  3723. >>> np.quantile(a, 0.5, axis=0)
  3724. array([6.5, 4.5, 2.5])
  3725. >>> np.quantile(a, 0.5, axis=1)
  3726. array([7., 2.])
  3727. >>> np.quantile(a, 0.5, axis=1, keepdims=True)
  3728. array([[7.],
  3729. [2.]])
  3730. >>> m = np.quantile(a, 0.5, axis=0)
  3731. >>> out = np.zeros_like(m)
  3732. >>> np.quantile(a, 0.5, axis=0, out=out)
  3733. array([6.5, 4.5, 2.5])
  3734. >>> m
  3735. array([6.5, 4.5, 2.5])
  3736. >>> b = a.copy()
  3737. >>> np.quantile(b, 0.5, axis=1, overwrite_input=True)
  3738. array([7., 2.])
  3739. >>> assert not np.all(a == b)
  3740. See also `numpy.percentile` for a visualization of most methods.
  3741. References
  3742. ----------
  3743. .. [1] R. J. Hyndman and Y. Fan,
  3744. "Sample quantiles in statistical packages,"
  3745. The American Statistician, 50(4), pp. 361-365, 1996
  3746. """
  3747. if interpolation is not None:
  3748. method = _check_interpolation_as_method(
  3749. method, interpolation, "quantile")
  3750. a = np.asanyarray(a)
  3751. if a.dtype.kind == "c":
  3752. raise TypeError("a must be an array of real numbers")
  3753. q = np.asanyarray(q)
  3754. if not _quantile_is_valid(q):
  3755. raise ValueError("Quantiles must be in the range [0, 1]")
  3756. return _quantile_unchecked(
  3757. a, q, axis, out, overwrite_input, method, keepdims)
  3758. def _quantile_unchecked(a,
  3759. q,
  3760. axis=None,
  3761. out=None,
  3762. overwrite_input=False,
  3763. method="linear",
  3764. keepdims=False):
  3765. """Assumes that q is in [0, 1], and is an ndarray"""
  3766. return _ureduce(a,
  3767. func=_quantile_ureduce_func,
  3768. q=q,
  3769. keepdims=keepdims,
  3770. axis=axis,
  3771. out=out,
  3772. overwrite_input=overwrite_input,
  3773. method=method)
  3774. def _quantile_is_valid(q):
  3775. # avoid expensive reductions, relevant for arrays with < O(1000) elements
  3776. if q.ndim == 1 and q.size < 10:
  3777. for i in range(q.size):
  3778. if not (0.0 <= q[i] <= 1.0):
  3779. return False
  3780. else:
  3781. if not (np.all(0 <= q) and np.all(q <= 1)):
  3782. return False
  3783. return True
  3784. def _check_interpolation_as_method(method, interpolation, fname):
  3785. # Deprecated NumPy 1.22, 2021-11-08
  3786. warnings.warn(
  3787. f"the `interpolation=` argument to {fname} was renamed to "
  3788. "`method=`, which has additional options.\n"
  3789. "Users of the modes 'nearest', 'lower', 'higher', or "
  3790. "'midpoint' are encouraged to review the method they used. "
  3791. "(Deprecated NumPy 1.22)",
  3792. DeprecationWarning, stacklevel=4)
  3793. if method != "linear":
  3794. # sanity check, we assume this basically never happens
  3795. raise TypeError(
  3796. "You shall not pass both `method` and `interpolation`!\n"
  3797. "(`interpolation` is Deprecated in favor of `method`)")
  3798. return interpolation
  3799. def _compute_virtual_index(n, quantiles, alpha: float, beta: float):
  3800. """
  3801. Compute the floating point indexes of an array for the linear
  3802. interpolation of quantiles.
  3803. n : array_like
  3804. The sample sizes.
  3805. quantiles : array_like
  3806. The quantiles values.
  3807. alpha : float
  3808. A constant used to correct the index computed.
  3809. beta : float
  3810. A constant used to correct the index computed.
  3811. alpha and beta values depend on the chosen method
  3812. (see quantile documentation)
  3813. Reference:
  3814. Hyndman&Fan paper "Sample Quantiles in Statistical Packages",
  3815. DOI: 10.1080/00031305.1996.10473566
  3816. """
  3817. return n * quantiles + (
  3818. alpha + quantiles * (1 - alpha - beta)
  3819. ) - 1
  3820. def _get_gamma(virtual_indexes, previous_indexes, method):
  3821. """
  3822. Compute gamma (a.k.a 'm' or 'weight') for the linear interpolation
  3823. of quantiles.
  3824. virtual_indexes : array_like
  3825. The indexes where the percentile is supposed to be found in the sorted
  3826. sample.
  3827. previous_indexes : array_like
  3828. The floor values of virtual_indexes.
  3829. interpolation : dict
  3830. The interpolation method chosen, which may have a specific rule
  3831. modifying gamma.
  3832. gamma is usually the fractional part of virtual_indexes but can be modified
  3833. by the interpolation method.
  3834. """
  3835. gamma = np.asanyarray(virtual_indexes - previous_indexes)
  3836. gamma = method["fix_gamma"](gamma, virtual_indexes)
  3837. return np.asanyarray(gamma)
  3838. def _lerp(a, b, t, out=None):
  3839. """
  3840. Compute the linear interpolation weighted by gamma on each point of
  3841. two same shape array.
  3842. a : array_like
  3843. Left bound.
  3844. b : array_like
  3845. Right bound.
  3846. t : array_like
  3847. The interpolation weight.
  3848. out : array_like
  3849. Output array.
  3850. """
  3851. diff_b_a = subtract(b, a)
  3852. # asanyarray is a stop-gap until gh-13105
  3853. lerp_interpolation = asanyarray(add(a, diff_b_a * t, out=out))
  3854. subtract(b, diff_b_a * (1 - t), out=lerp_interpolation, where=t >= 0.5,
  3855. casting='unsafe', dtype=type(lerp_interpolation.dtype))
  3856. if lerp_interpolation.ndim == 0 and out is None:
  3857. lerp_interpolation = lerp_interpolation[()] # unpack 0d arrays
  3858. return lerp_interpolation
  3859. def _get_gamma_mask(shape, default_value, conditioned_value, where):
  3860. out = np.full(shape, default_value)
  3861. np.copyto(out, conditioned_value, where=where, casting="unsafe")
  3862. return out
  3863. def _discret_interpolation_to_boundaries(index, gamma_condition_fun):
  3864. previous = np.floor(index)
  3865. next = previous + 1
  3866. gamma = index - previous
  3867. res = _get_gamma_mask(shape=index.shape,
  3868. default_value=next,
  3869. conditioned_value=previous,
  3870. where=gamma_condition_fun(gamma, index)
  3871. ).astype(np.intp)
  3872. # Some methods can lead to out-of-bound integers, clip them:
  3873. res[res < 0] = 0
  3874. return res
  3875. def _closest_observation(n, quantiles):
  3876. gamma_fun = lambda gamma, index: (gamma == 0) & (np.floor(index) % 2 == 0)
  3877. return _discret_interpolation_to_boundaries((n * quantiles) - 1 - 0.5,
  3878. gamma_fun)
  3879. def _inverted_cdf(n, quantiles):
  3880. gamma_fun = lambda gamma, _: (gamma == 0)
  3881. return _discret_interpolation_to_boundaries((n * quantiles) - 1,
  3882. gamma_fun)
  3883. def _quantile_ureduce_func(
  3884. a: np.array,
  3885. q: np.array,
  3886. axis: int = None,
  3887. out=None,
  3888. overwrite_input: bool = False,
  3889. method="linear",
  3890. ) -> np.array:
  3891. if q.ndim > 2:
  3892. # The code below works fine for nd, but it might not have useful
  3893. # semantics. For now, keep the supported dimensions the same as it was
  3894. # before.
  3895. raise ValueError("q must be a scalar or 1d")
  3896. if overwrite_input:
  3897. if axis is None:
  3898. axis = 0
  3899. arr = a.ravel()
  3900. else:
  3901. arr = a
  3902. else:
  3903. if axis is None:
  3904. axis = 0
  3905. arr = a.flatten()
  3906. else:
  3907. arr = a.copy()
  3908. result = _quantile(arr,
  3909. quantiles=q,
  3910. axis=axis,
  3911. method=method,
  3912. out=out)
  3913. return result
  3914. def _get_indexes(arr, virtual_indexes, valid_values_count):
  3915. """
  3916. Get the valid indexes of arr neighbouring virtual_indexes.
  3917. Note
  3918. This is a companion function to linear interpolation of
  3919. Quantiles
  3920. Returns
  3921. -------
  3922. (previous_indexes, next_indexes): Tuple
  3923. A Tuple of virtual_indexes neighbouring indexes
  3924. """
  3925. previous_indexes = np.asanyarray(np.floor(virtual_indexes))
  3926. next_indexes = np.asanyarray(previous_indexes + 1)
  3927. indexes_above_bounds = virtual_indexes >= valid_values_count - 1
  3928. # When indexes is above max index, take the max value of the array
  3929. if indexes_above_bounds.any():
  3930. previous_indexes[indexes_above_bounds] = -1
  3931. next_indexes[indexes_above_bounds] = -1
  3932. # When indexes is below min index, take the min value of the array
  3933. indexes_below_bounds = virtual_indexes < 0
  3934. if indexes_below_bounds.any():
  3935. previous_indexes[indexes_below_bounds] = 0
  3936. next_indexes[indexes_below_bounds] = 0
  3937. if np.issubdtype(arr.dtype, np.inexact):
  3938. # After the sort, slices having NaNs will have for last element a NaN
  3939. virtual_indexes_nans = np.isnan(virtual_indexes)
  3940. if virtual_indexes_nans.any():
  3941. previous_indexes[virtual_indexes_nans] = -1
  3942. next_indexes[virtual_indexes_nans] = -1
  3943. previous_indexes = previous_indexes.astype(np.intp)
  3944. next_indexes = next_indexes.astype(np.intp)
  3945. return previous_indexes, next_indexes
  3946. def _quantile(
  3947. arr: np.array,
  3948. quantiles: np.array,
  3949. axis: int = -1,
  3950. method="linear",
  3951. out=None,
  3952. ):
  3953. """
  3954. Private function that doesn't support extended axis or keepdims.
  3955. These methods are extended to this function using _ureduce
  3956. See nanpercentile for parameter usage
  3957. It computes the quantiles of the array for the given axis.
  3958. A linear interpolation is performed based on the `interpolation`.
  3959. By default, the method is "linear" where alpha == beta == 1 which
  3960. performs the 7th method of Hyndman&Fan.
  3961. With "median_unbiased" we get alpha == beta == 1/3
  3962. thus the 8th method of Hyndman&Fan.
  3963. """
  3964. # --- Setup
  3965. arr = np.asanyarray(arr)
  3966. values_count = arr.shape[axis]
  3967. # The dimensions of `q` are prepended to the output shape, so we need the
  3968. # axis being sampled from `arr` to be last.
  3969. if axis != 0: # But moveaxis is slow, so only call it if necessary.
  3970. arr = np.moveaxis(arr, axis, destination=0)
  3971. # --- Computation of indexes
  3972. # Index where to find the value in the sorted array.
  3973. # Virtual because it is a floating point value, not an valid index.
  3974. # The nearest neighbours are used for interpolation
  3975. try:
  3976. method = _QuantileMethods[method]
  3977. except KeyError:
  3978. raise ValueError(
  3979. f"{method!r} is not a valid method. Use one of: "
  3980. f"{_QuantileMethods.keys()}") from None
  3981. virtual_indexes = method["get_virtual_index"](values_count, quantiles)
  3982. virtual_indexes = np.asanyarray(virtual_indexes)
  3983. supports_nans = (
  3984. np.issubdtype(arr.dtype, np.inexact) or arr.dtype.kind in 'Mm')
  3985. if np.issubdtype(virtual_indexes.dtype, np.integer):
  3986. # No interpolation needed, take the points along axis
  3987. if supports_nans:
  3988. # may contain nan, which would sort to the end
  3989. arr.partition(concatenate((virtual_indexes.ravel(), [-1])), axis=0)
  3990. slices_having_nans = np.isnan(arr[-1, ...])
  3991. else:
  3992. # cannot contain nan
  3993. arr.partition(virtual_indexes.ravel(), axis=0)
  3994. slices_having_nans = np.array(False, dtype=bool)
  3995. result = take(arr, virtual_indexes, axis=0, out=out)
  3996. else:
  3997. previous_indexes, next_indexes = _get_indexes(arr,
  3998. virtual_indexes,
  3999. values_count)
  4000. # --- Sorting
  4001. arr.partition(
  4002. np.unique(np.concatenate(([0, -1],
  4003. previous_indexes.ravel(),
  4004. next_indexes.ravel(),
  4005. ))),
  4006. axis=0)
  4007. if supports_nans:
  4008. slices_having_nans = np.isnan(arr[-1, ...])
  4009. else:
  4010. slices_having_nans = None
  4011. # --- Get values from indexes
  4012. previous = arr[previous_indexes]
  4013. next = arr[next_indexes]
  4014. # --- Linear interpolation
  4015. gamma = _get_gamma(virtual_indexes, previous_indexes, method)
  4016. result_shape = virtual_indexes.shape + (1,) * (arr.ndim - 1)
  4017. gamma = gamma.reshape(result_shape)
  4018. result = _lerp(previous,
  4019. next,
  4020. gamma,
  4021. out=out)
  4022. if np.any(slices_having_nans):
  4023. if result.ndim == 0 and out is None:
  4024. # can't write to a scalar, but indexing will be correct
  4025. result = arr[-1]
  4026. else:
  4027. np.copyto(result, arr[-1, ...], where=slices_having_nans)
  4028. return result
  4029. def _trapz_dispatcher(y, x=None, dx=None, axis=None):
  4030. return (y, x)
  4031. @array_function_dispatch(_trapz_dispatcher)
  4032. def trapz(y, x=None, dx=1.0, axis=-1):
  4033. r"""
  4034. Integrate along the given axis using the composite trapezoidal rule.
  4035. If `x` is provided, the integration happens in sequence along its
  4036. elements - they are not sorted.
  4037. Integrate `y` (`x`) along each 1d slice on the given axis, compute
  4038. :math:`\int y(x) dx`.
  4039. When `x` is specified, this integrates along the parametric curve,
  4040. computing :math:`\int_t y(t) dt =
  4041. \int_t y(t) \left.\frac{dx}{dt}\right|_{x=x(t)} dt`.
  4042. Parameters
  4043. ----------
  4044. y : array_like
  4045. Input array to integrate.
  4046. x : array_like, optional
  4047. The sample points corresponding to the `y` values. If `x` is None,
  4048. the sample points are assumed to be evenly spaced `dx` apart. The
  4049. default is None.
  4050. dx : scalar, optional
  4051. The spacing between sample points when `x` is None. The default is 1.
  4052. axis : int, optional
  4053. The axis along which to integrate.
  4054. Returns
  4055. -------
  4056. trapz : float or ndarray
  4057. Definite integral of `y` = n-dimensional array as approximated along
  4058. a single axis by the trapezoidal rule. If `y` is a 1-dimensional array,
  4059. then the result is a float. If `n` is greater than 1, then the result
  4060. is an `n`-1 dimensional array.
  4061. See Also
  4062. --------
  4063. sum, cumsum
  4064. Notes
  4065. -----
  4066. Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
  4067. will be taken from `y` array, by default x-axis distances between
  4068. points will be 1.0, alternatively they can be provided with `x` array
  4069. or with `dx` scalar. Return value will be equal to combined area under
  4070. the red lines.
  4071. References
  4072. ----------
  4073. .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Trapezoidal_rule
  4074. .. [2] Illustration image:
  4075. https://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
  4076. Examples
  4077. --------
  4078. Use the trapezoidal rule on evenly spaced points:
  4079. >>> np.trapz([1, 2, 3])
  4080. 4.0
  4081. The spacing between sample points can be selected by either the
  4082. ``x`` or ``dx`` arguments:
  4083. >>> np.trapz([1, 2, 3], x=[4, 6, 8])
  4084. 8.0
  4085. >>> np.trapz([1, 2, 3], dx=2)
  4086. 8.0
  4087. Using a decreasing ``x`` corresponds to integrating in reverse:
  4088. >>> np.trapz([1, 2, 3], x=[8, 6, 4])
  4089. -8.0
  4090. More generally ``x`` is used to integrate along a parametric curve. We can
  4091. estimate the integral :math:`\int_0^1 x^2 = 1/3` using:
  4092. >>> x = np.linspace(0, 1, num=50)
  4093. >>> y = x**2
  4094. >>> np.trapz(y, x)
  4095. 0.33340274885464394
  4096. Or estimate the area of a circle, noting we repeat the sample which closes
  4097. the curve:
  4098. >>> theta = np.linspace(0, 2 * np.pi, num=1000, endpoint=True)
  4099. >>> np.trapz(np.cos(theta), x=np.sin(theta))
  4100. 3.141571941375841
  4101. ``np.trapz`` can be applied along a specified axis to do multiple
  4102. computations in one call:
  4103. >>> a = np.arange(6).reshape(2, 3)
  4104. >>> a
  4105. array([[0, 1, 2],
  4106. [3, 4, 5]])
  4107. >>> np.trapz(a, axis=0)
  4108. array([1.5, 2.5, 3.5])
  4109. >>> np.trapz(a, axis=1)
  4110. array([2., 8.])
  4111. """
  4112. y = asanyarray(y)
  4113. if x is None:
  4114. d = dx
  4115. else:
  4116. x = asanyarray(x)
  4117. if x.ndim == 1:
  4118. d = diff(x)
  4119. # reshape to correct shape
  4120. shape = [1]*y.ndim
  4121. shape[axis] = d.shape[0]
  4122. d = d.reshape(shape)
  4123. else:
  4124. d = diff(x, axis=axis)
  4125. nd = y.ndim
  4126. slice1 = [slice(None)]*nd
  4127. slice2 = [slice(None)]*nd
  4128. slice1[axis] = slice(1, None)
  4129. slice2[axis] = slice(None, -1)
  4130. try:
  4131. ret = (d * (y[tuple(slice1)] + y[tuple(slice2)]) / 2.0).sum(axis)
  4132. except ValueError:
  4133. # Operations didn't work, cast to ndarray
  4134. d = np.asarray(d)
  4135. y = np.asarray(y)
  4136. ret = add.reduce(d * (y[tuple(slice1)]+y[tuple(slice2)])/2.0, axis)
  4137. return ret
  4138. # __array_function__ has no __code__ or other attributes normal Python funcs we
  4139. # wrap everything into a C callable. SciPy however, tries to "clone" `trapz`
  4140. # into a new Python function which requires `__code__` and a few other
  4141. # attributes. So we create a dummy clone and copy over its attributes allowing
  4142. # SciPy <= 1.10 to work: https://github.com/scipy/scipy/issues/17811
  4143. assert not hasattr(trapz, "__code__")
  4144. def _fake_trapz(y, x=None, dx=1.0, axis=-1):
  4145. return trapz(y, x=x, dx=dx, axis=axis)
  4146. trapz.__code__ = _fake_trapz.__code__
  4147. trapz.__globals__ = _fake_trapz.__globals__
  4148. trapz.__defaults__ = _fake_trapz.__defaults__
  4149. trapz.__closure__ = _fake_trapz.__closure__
  4150. trapz.__kwdefaults__ = _fake_trapz.__kwdefaults__
  4151. def _meshgrid_dispatcher(*xi, copy=None, sparse=None, indexing=None):
  4152. return xi
  4153. # Based on scitools meshgrid
  4154. @array_function_dispatch(_meshgrid_dispatcher)
  4155. def meshgrid(*xi, copy=True, sparse=False, indexing='xy'):
  4156. """
  4157. Return a list of coordinate matrices from coordinate vectors.
  4158. Make N-D coordinate arrays for vectorized evaluations of
  4159. N-D scalar/vector fields over N-D grids, given
  4160. one-dimensional coordinate arrays x1, x2,..., xn.
  4161. .. versionchanged:: 1.9
  4162. 1-D and 0-D cases are allowed.
  4163. Parameters
  4164. ----------
  4165. x1, x2,..., xn : array_like
  4166. 1-D arrays representing the coordinates of a grid.
  4167. indexing : {'xy', 'ij'}, optional
  4168. Cartesian ('xy', default) or matrix ('ij') indexing of output.
  4169. See Notes for more details.
  4170. .. versionadded:: 1.7.0
  4171. sparse : bool, optional
  4172. If True the shape of the returned coordinate array for dimension *i*
  4173. is reduced from ``(N1, ..., Ni, ... Nn)`` to
  4174. ``(1, ..., 1, Ni, 1, ..., 1)``. These sparse coordinate grids are
  4175. intended to be use with :ref:`basics.broadcasting`. When all
  4176. coordinates are used in an expression, broadcasting still leads to a
  4177. fully-dimensonal result array.
  4178. Default is False.
  4179. .. versionadded:: 1.7.0
  4180. copy : bool, optional
  4181. If False, a view into the original arrays are returned in order to
  4182. conserve memory. Default is True. Please note that
  4183. ``sparse=False, copy=False`` will likely return non-contiguous
  4184. arrays. Furthermore, more than one element of a broadcast array
  4185. may refer to a single memory location. If you need to write to the
  4186. arrays, make copies first.
  4187. .. versionadded:: 1.7.0
  4188. Returns
  4189. -------
  4190. X1, X2,..., XN : list of ndarrays
  4191. For vectors `x1`, `x2`,..., `xn` with lengths ``Ni=len(xi)``,
  4192. returns ``(N1, N2, N3,..., Nn)`` shaped arrays if indexing='ij'
  4193. or ``(N2, N1, N3,..., Nn)`` shaped arrays if indexing='xy'
  4194. with the elements of `xi` repeated to fill the matrix along
  4195. the first dimension for `x1`, the second for `x2` and so on.
  4196. Notes
  4197. -----
  4198. This function supports both indexing conventions through the indexing
  4199. keyword argument. Giving the string 'ij' returns a meshgrid with
  4200. matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing.
  4201. In the 2-D case with inputs of length M and N, the outputs are of shape
  4202. (N, M) for 'xy' indexing and (M, N) for 'ij' indexing. In the 3-D case
  4203. with inputs of length M, N and P, outputs are of shape (N, M, P) for
  4204. 'xy' indexing and (M, N, P) for 'ij' indexing. The difference is
  4205. illustrated by the following code snippet::
  4206. xv, yv = np.meshgrid(x, y, indexing='ij')
  4207. for i in range(nx):
  4208. for j in range(ny):
  4209. # treat xv[i,j], yv[i,j]
  4210. xv, yv = np.meshgrid(x, y, indexing='xy')
  4211. for i in range(nx):
  4212. for j in range(ny):
  4213. # treat xv[j,i], yv[j,i]
  4214. In the 1-D and 0-D case, the indexing and sparse keywords have no effect.
  4215. See Also
  4216. --------
  4217. mgrid : Construct a multi-dimensional "meshgrid" using indexing notation.
  4218. ogrid : Construct an open multi-dimensional "meshgrid" using indexing
  4219. notation.
  4220. how-to-index
  4221. Examples
  4222. --------
  4223. >>> nx, ny = (3, 2)
  4224. >>> x = np.linspace(0, 1, nx)
  4225. >>> y = np.linspace(0, 1, ny)
  4226. >>> xv, yv = np.meshgrid(x, y)
  4227. >>> xv
  4228. array([[0. , 0.5, 1. ],
  4229. [0. , 0.5, 1. ]])
  4230. >>> yv
  4231. array([[0., 0., 0.],
  4232. [1., 1., 1.]])
  4233. The result of `meshgrid` is a coordinate grid:
  4234. >>> import matplotlib.pyplot as plt
  4235. >>> plt.plot(xv, yv, marker='o', color='k', linestyle='none')
  4236. >>> plt.show()
  4237. You can create sparse output arrays to save memory and computation time.
  4238. >>> xv, yv = np.meshgrid(x, y, sparse=True)
  4239. >>> xv
  4240. array([[0. , 0.5, 1. ]])
  4241. >>> yv
  4242. array([[0.],
  4243. [1.]])
  4244. `meshgrid` is very useful to evaluate functions on a grid. If the
  4245. function depends on all coordinates, both dense and sparse outputs can be
  4246. used.
  4247. >>> x = np.linspace(-5, 5, 101)
  4248. >>> y = np.linspace(-5, 5, 101)
  4249. >>> # full coordinate arrays
  4250. >>> xx, yy = np.meshgrid(x, y)
  4251. >>> zz = np.sqrt(xx**2 + yy**2)
  4252. >>> xx.shape, yy.shape, zz.shape
  4253. ((101, 101), (101, 101), (101, 101))
  4254. >>> # sparse coordinate arrays
  4255. >>> xs, ys = np.meshgrid(x, y, sparse=True)
  4256. >>> zs = np.sqrt(xs**2 + ys**2)
  4257. >>> xs.shape, ys.shape, zs.shape
  4258. ((1, 101), (101, 1), (101, 101))
  4259. >>> np.array_equal(zz, zs)
  4260. True
  4261. >>> h = plt.contourf(x, y, zs)
  4262. >>> plt.axis('scaled')
  4263. >>> plt.colorbar()
  4264. >>> plt.show()
  4265. """
  4266. ndim = len(xi)
  4267. if indexing not in ['xy', 'ij']:
  4268. raise ValueError(
  4269. "Valid values for `indexing` are 'xy' and 'ij'.")
  4270. s0 = (1,) * ndim
  4271. output = [np.asanyarray(x).reshape(s0[:i] + (-1,) + s0[i + 1:])
  4272. for i, x in enumerate(xi)]
  4273. if indexing == 'xy' and ndim > 1:
  4274. # switch first and second axis
  4275. output[0].shape = (1, -1) + s0[2:]
  4276. output[1].shape = (-1, 1) + s0[2:]
  4277. if not sparse:
  4278. # Return the full N-D matrix (not only the 1-D vector)
  4279. output = np.broadcast_arrays(*output, subok=True)
  4280. if copy:
  4281. output = [x.copy() for x in output]
  4282. return output
  4283. def _delete_dispatcher(arr, obj, axis=None):
  4284. return (arr, obj)
  4285. @array_function_dispatch(_delete_dispatcher)
  4286. def delete(arr, obj, axis=None):
  4287. """
  4288. Return a new array with sub-arrays along an axis deleted. For a one
  4289. dimensional array, this returns those entries not returned by
  4290. `arr[obj]`.
  4291. Parameters
  4292. ----------
  4293. arr : array_like
  4294. Input array.
  4295. obj : slice, int or array of ints
  4296. Indicate indices of sub-arrays to remove along the specified axis.
  4297. .. versionchanged:: 1.19.0
  4298. Boolean indices are now treated as a mask of elements to remove,
  4299. rather than being cast to the integers 0 and 1.
  4300. axis : int, optional
  4301. The axis along which to delete the subarray defined by `obj`.
  4302. If `axis` is None, `obj` is applied to the flattened array.
  4303. Returns
  4304. -------
  4305. out : ndarray
  4306. A copy of `arr` with the elements specified by `obj` removed. Note
  4307. that `delete` does not occur in-place. If `axis` is None, `out` is
  4308. a flattened array.
  4309. See Also
  4310. --------
  4311. insert : Insert elements into an array.
  4312. append : Append elements at the end of an array.
  4313. Notes
  4314. -----
  4315. Often it is preferable to use a boolean mask. For example:
  4316. >>> arr = np.arange(12) + 1
  4317. >>> mask = np.ones(len(arr), dtype=bool)
  4318. >>> mask[[0,2,4]] = False
  4319. >>> result = arr[mask,...]
  4320. Is equivalent to ``np.delete(arr, [0,2,4], axis=0)``, but allows further
  4321. use of `mask`.
  4322. Examples
  4323. --------
  4324. >>> arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
  4325. >>> arr
  4326. array([[ 1, 2, 3, 4],
  4327. [ 5, 6, 7, 8],
  4328. [ 9, 10, 11, 12]])
  4329. >>> np.delete(arr, 1, 0)
  4330. array([[ 1, 2, 3, 4],
  4331. [ 9, 10, 11, 12]])
  4332. >>> np.delete(arr, np.s_[::2], 1)
  4333. array([[ 2, 4],
  4334. [ 6, 8],
  4335. [10, 12]])
  4336. >>> np.delete(arr, [1,3,5], None)
  4337. array([ 1, 3, 5, 7, 8, 9, 10, 11, 12])
  4338. """
  4339. wrap = None
  4340. if type(arr) is not ndarray:
  4341. try:
  4342. wrap = arr.__array_wrap__
  4343. except AttributeError:
  4344. pass
  4345. arr = asarray(arr)
  4346. ndim = arr.ndim
  4347. arrorder = 'F' if arr.flags.fnc else 'C'
  4348. if axis is None:
  4349. if ndim != 1:
  4350. arr = arr.ravel()
  4351. # needed for np.matrix, which is still not 1d after being ravelled
  4352. ndim = arr.ndim
  4353. axis = ndim - 1
  4354. else:
  4355. axis = normalize_axis_index(axis, ndim)
  4356. slobj = [slice(None)]*ndim
  4357. N = arr.shape[axis]
  4358. newshape = list(arr.shape)
  4359. if isinstance(obj, slice):
  4360. start, stop, step = obj.indices(N)
  4361. xr = range(start, stop, step)
  4362. numtodel = len(xr)
  4363. if numtodel <= 0:
  4364. if wrap:
  4365. return wrap(arr.copy(order=arrorder))
  4366. else:
  4367. return arr.copy(order=arrorder)
  4368. # Invert if step is negative:
  4369. if step < 0:
  4370. step = -step
  4371. start = xr[-1]
  4372. stop = xr[0] + 1
  4373. newshape[axis] -= numtodel
  4374. new = empty(newshape, arr.dtype, arrorder)
  4375. # copy initial chunk
  4376. if start == 0:
  4377. pass
  4378. else:
  4379. slobj[axis] = slice(None, start)
  4380. new[tuple(slobj)] = arr[tuple(slobj)]
  4381. # copy end chunk
  4382. if stop == N:
  4383. pass
  4384. else:
  4385. slobj[axis] = slice(stop-numtodel, None)
  4386. slobj2 = [slice(None)]*ndim
  4387. slobj2[axis] = slice(stop, None)
  4388. new[tuple(slobj)] = arr[tuple(slobj2)]
  4389. # copy middle pieces
  4390. if step == 1:
  4391. pass
  4392. else: # use array indexing.
  4393. keep = ones(stop-start, dtype=bool)
  4394. keep[:stop-start:step] = False
  4395. slobj[axis] = slice(start, stop-numtodel)
  4396. slobj2 = [slice(None)]*ndim
  4397. slobj2[axis] = slice(start, stop)
  4398. arr = arr[tuple(slobj2)]
  4399. slobj2[axis] = keep
  4400. new[tuple(slobj)] = arr[tuple(slobj2)]
  4401. if wrap:
  4402. return wrap(new)
  4403. else:
  4404. return new
  4405. if isinstance(obj, (int, integer)) and not isinstance(obj, bool):
  4406. single_value = True
  4407. else:
  4408. single_value = False
  4409. _obj = obj
  4410. obj = np.asarray(obj)
  4411. # `size == 0` to allow empty lists similar to indexing, but (as there)
  4412. # is really too generic:
  4413. if obj.size == 0 and not isinstance(_obj, np.ndarray):
  4414. obj = obj.astype(intp)
  4415. elif obj.size == 1 and obj.dtype.kind in "ui":
  4416. # For a size 1 integer array we can use the single-value path
  4417. # (most dtypes, except boolean, should just fail later).
  4418. obj = obj.item()
  4419. single_value = True
  4420. if single_value:
  4421. # optimization for a single value
  4422. if (obj < -N or obj >= N):
  4423. raise IndexError(
  4424. "index %i is out of bounds for axis %i with "
  4425. "size %i" % (obj, axis, N))
  4426. if (obj < 0):
  4427. obj += N
  4428. newshape[axis] -= 1
  4429. new = empty(newshape, arr.dtype, arrorder)
  4430. slobj[axis] = slice(None, obj)
  4431. new[tuple(slobj)] = arr[tuple(slobj)]
  4432. slobj[axis] = slice(obj, None)
  4433. slobj2 = [slice(None)]*ndim
  4434. slobj2[axis] = slice(obj+1, None)
  4435. new[tuple(slobj)] = arr[tuple(slobj2)]
  4436. else:
  4437. if obj.dtype == bool:
  4438. if obj.shape != (N,):
  4439. raise ValueError('boolean array argument obj to delete '
  4440. 'must be one dimensional and match the axis '
  4441. 'length of {}'.format(N))
  4442. # optimization, the other branch is slower
  4443. keep = ~obj
  4444. else:
  4445. keep = ones(N, dtype=bool)
  4446. keep[obj,] = False
  4447. slobj[axis] = keep
  4448. new = arr[tuple(slobj)]
  4449. if wrap:
  4450. return wrap(new)
  4451. else:
  4452. return new
  4453. def _insert_dispatcher(arr, obj, values, axis=None):
  4454. return (arr, obj, values)
  4455. @array_function_dispatch(_insert_dispatcher)
  4456. def insert(arr, obj, values, axis=None):
  4457. """
  4458. Insert values along the given axis before the given indices.
  4459. Parameters
  4460. ----------
  4461. arr : array_like
  4462. Input array.
  4463. obj : int, slice or sequence of ints
  4464. Object that defines the index or indices before which `values` is
  4465. inserted.
  4466. .. versionadded:: 1.8.0
  4467. Support for multiple insertions when `obj` is a single scalar or a
  4468. sequence with one element (similar to calling insert multiple
  4469. times).
  4470. values : array_like
  4471. Values to insert into `arr`. If the type of `values` is different
  4472. from that of `arr`, `values` is converted to the type of `arr`.
  4473. `values` should be shaped so that ``arr[...,obj,...] = values``
  4474. is legal.
  4475. axis : int, optional
  4476. Axis along which to insert `values`. If `axis` is None then `arr`
  4477. is flattened first.
  4478. Returns
  4479. -------
  4480. out : ndarray
  4481. A copy of `arr` with `values` inserted. Note that `insert`
  4482. does not occur in-place: a new array is returned. If
  4483. `axis` is None, `out` is a flattened array.
  4484. See Also
  4485. --------
  4486. append : Append elements at the end of an array.
  4487. concatenate : Join a sequence of arrays along an existing axis.
  4488. delete : Delete elements from an array.
  4489. Notes
  4490. -----
  4491. Note that for higher dimensional inserts ``obj=0`` behaves very different
  4492. from ``obj=[0]`` just like ``arr[:,0,:] = values`` is different from
  4493. ``arr[:,[0],:] = values``.
  4494. Examples
  4495. --------
  4496. >>> a = np.array([[1, 1], [2, 2], [3, 3]])
  4497. >>> a
  4498. array([[1, 1],
  4499. [2, 2],
  4500. [3, 3]])
  4501. >>> np.insert(a, 1, 5)
  4502. array([1, 5, 1, ..., 2, 3, 3])
  4503. >>> np.insert(a, 1, 5, axis=1)
  4504. array([[1, 5, 1],
  4505. [2, 5, 2],
  4506. [3, 5, 3]])
  4507. Difference between sequence and scalars:
  4508. >>> np.insert(a, [1], [[1],[2],[3]], axis=1)
  4509. array([[1, 1, 1],
  4510. [2, 2, 2],
  4511. [3, 3, 3]])
  4512. >>> np.array_equal(np.insert(a, 1, [1, 2, 3], axis=1),
  4513. ... np.insert(a, [1], [[1],[2],[3]], axis=1))
  4514. True
  4515. >>> b = a.flatten()
  4516. >>> b
  4517. array([1, 1, 2, 2, 3, 3])
  4518. >>> np.insert(b, [2, 2], [5, 6])
  4519. array([1, 1, 5, ..., 2, 3, 3])
  4520. >>> np.insert(b, slice(2, 4), [5, 6])
  4521. array([1, 1, 5, ..., 2, 3, 3])
  4522. >>> np.insert(b, [2, 2], [7.13, False]) # type casting
  4523. array([1, 1, 7, ..., 2, 3, 3])
  4524. >>> x = np.arange(8).reshape(2, 4)
  4525. >>> idx = (1, 3)
  4526. >>> np.insert(x, idx, 999, axis=1)
  4527. array([[ 0, 999, 1, 2, 999, 3],
  4528. [ 4, 999, 5, 6, 999, 7]])
  4529. """
  4530. wrap = None
  4531. if type(arr) is not ndarray:
  4532. try:
  4533. wrap = arr.__array_wrap__
  4534. except AttributeError:
  4535. pass
  4536. arr = asarray(arr)
  4537. ndim = arr.ndim
  4538. arrorder = 'F' if arr.flags.fnc else 'C'
  4539. if axis is None:
  4540. if ndim != 1:
  4541. arr = arr.ravel()
  4542. # needed for np.matrix, which is still not 1d after being ravelled
  4543. ndim = arr.ndim
  4544. axis = ndim - 1
  4545. else:
  4546. axis = normalize_axis_index(axis, ndim)
  4547. slobj = [slice(None)]*ndim
  4548. N = arr.shape[axis]
  4549. newshape = list(arr.shape)
  4550. if isinstance(obj, slice):
  4551. # turn it into a range object
  4552. indices = arange(*obj.indices(N), dtype=intp)
  4553. else:
  4554. # need to copy obj, because indices will be changed in-place
  4555. indices = np.array(obj)
  4556. if indices.dtype == bool:
  4557. # See also delete
  4558. # 2012-10-11, NumPy 1.8
  4559. warnings.warn(
  4560. "in the future insert will treat boolean arrays and "
  4561. "array-likes as a boolean index instead of casting it to "
  4562. "integer", FutureWarning, stacklevel=2)
  4563. indices = indices.astype(intp)
  4564. # Code after warning period:
  4565. #if obj.ndim != 1:
  4566. # raise ValueError('boolean array argument obj to insert '
  4567. # 'must be one dimensional')
  4568. #indices = np.flatnonzero(obj)
  4569. elif indices.ndim > 1:
  4570. raise ValueError(
  4571. "index array argument obj to insert must be one dimensional "
  4572. "or scalar")
  4573. if indices.size == 1:
  4574. index = indices.item()
  4575. if index < -N or index > N:
  4576. raise IndexError(f"index {obj} is out of bounds for axis {axis} "
  4577. f"with size {N}")
  4578. if (index < 0):
  4579. index += N
  4580. # There are some object array corner cases here, but we cannot avoid
  4581. # that:
  4582. values = array(values, copy=False, ndmin=arr.ndim, dtype=arr.dtype)
  4583. if indices.ndim == 0:
  4584. # broadcasting is very different here, since a[:,0,:] = ... behaves
  4585. # very different from a[:,[0],:] = ...! This changes values so that
  4586. # it works likes the second case. (here a[:,0:1,:])
  4587. values = np.moveaxis(values, 0, axis)
  4588. numnew = values.shape[axis]
  4589. newshape[axis] += numnew
  4590. new = empty(newshape, arr.dtype, arrorder)
  4591. slobj[axis] = slice(None, index)
  4592. new[tuple(slobj)] = arr[tuple(slobj)]
  4593. slobj[axis] = slice(index, index+numnew)
  4594. new[tuple(slobj)] = values
  4595. slobj[axis] = slice(index+numnew, None)
  4596. slobj2 = [slice(None)] * ndim
  4597. slobj2[axis] = slice(index, None)
  4598. new[tuple(slobj)] = arr[tuple(slobj2)]
  4599. if wrap:
  4600. return wrap(new)
  4601. return new
  4602. elif indices.size == 0 and not isinstance(obj, np.ndarray):
  4603. # Can safely cast the empty list to intp
  4604. indices = indices.astype(intp)
  4605. indices[indices < 0] += N
  4606. numnew = len(indices)
  4607. order = indices.argsort(kind='mergesort') # stable sort
  4608. indices[order] += np.arange(numnew)
  4609. newshape[axis] += numnew
  4610. old_mask = ones(newshape[axis], dtype=bool)
  4611. old_mask[indices] = False
  4612. new = empty(newshape, arr.dtype, arrorder)
  4613. slobj2 = [slice(None)]*ndim
  4614. slobj[axis] = indices
  4615. slobj2[axis] = old_mask
  4616. new[tuple(slobj)] = values
  4617. new[tuple(slobj2)] = arr
  4618. if wrap:
  4619. return wrap(new)
  4620. return new
  4621. def _append_dispatcher(arr, values, axis=None):
  4622. return (arr, values)
  4623. @array_function_dispatch(_append_dispatcher)
  4624. def append(arr, values, axis=None):
  4625. """
  4626. Append values to the end of an array.
  4627. Parameters
  4628. ----------
  4629. arr : array_like
  4630. Values are appended to a copy of this array.
  4631. values : array_like
  4632. These values are appended to a copy of `arr`. It must be of the
  4633. correct shape (the same shape as `arr`, excluding `axis`). If
  4634. `axis` is not specified, `values` can be any shape and will be
  4635. flattened before use.
  4636. axis : int, optional
  4637. The axis along which `values` are appended. If `axis` is not
  4638. given, both `arr` and `values` are flattened before use.
  4639. Returns
  4640. -------
  4641. append : ndarray
  4642. A copy of `arr` with `values` appended to `axis`. Note that
  4643. `append` does not occur in-place: a new array is allocated and
  4644. filled. If `axis` is None, `out` is a flattened array.
  4645. See Also
  4646. --------
  4647. insert : Insert elements into an array.
  4648. delete : Delete elements from an array.
  4649. Examples
  4650. --------
  4651. >>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
  4652. array([1, 2, 3, ..., 7, 8, 9])
  4653. When `axis` is specified, `values` must have the correct shape.
  4654. >>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
  4655. array([[1, 2, 3],
  4656. [4, 5, 6],
  4657. [7, 8, 9]])
  4658. >>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
  4659. Traceback (most recent call last):
  4660. ...
  4661. ValueError: all the input arrays must have same number of dimensions, but
  4662. the array at index 0 has 2 dimension(s) and the array at index 1 has 1
  4663. dimension(s)
  4664. """
  4665. arr = asanyarray(arr)
  4666. if axis is None:
  4667. if arr.ndim != 1:
  4668. arr = arr.ravel()
  4669. values = ravel(values)
  4670. axis = arr.ndim-1
  4671. return concatenate((arr, values), axis=axis)
  4672. def _digitize_dispatcher(x, bins, right=None):
  4673. return (x, bins)
  4674. @array_function_dispatch(_digitize_dispatcher)
  4675. def digitize(x, bins, right=False):
  4676. """
  4677. Return the indices of the bins to which each value in input array belongs.
  4678. ========= ============= ============================
  4679. `right` order of bins returned index `i` satisfies
  4680. ========= ============= ============================
  4681. ``False`` increasing ``bins[i-1] <= x < bins[i]``
  4682. ``True`` increasing ``bins[i-1] < x <= bins[i]``
  4683. ``False`` decreasing ``bins[i-1] > x >= bins[i]``
  4684. ``True`` decreasing ``bins[i-1] >= x > bins[i]``
  4685. ========= ============= ============================
  4686. If values in `x` are beyond the bounds of `bins`, 0 or ``len(bins)`` is
  4687. returned as appropriate.
  4688. Parameters
  4689. ----------
  4690. x : array_like
  4691. Input array to be binned. Prior to NumPy 1.10.0, this array had to
  4692. be 1-dimensional, but can now have any shape.
  4693. bins : array_like
  4694. Array of bins. It has to be 1-dimensional and monotonic.
  4695. right : bool, optional
  4696. Indicating whether the intervals include the right or the left bin
  4697. edge. Default behavior is (right==False) indicating that the interval
  4698. does not include the right edge. The left bin end is open in this
  4699. case, i.e., bins[i-1] <= x < bins[i] is the default behavior for
  4700. monotonically increasing bins.
  4701. Returns
  4702. -------
  4703. indices : ndarray of ints
  4704. Output array of indices, of same shape as `x`.
  4705. Raises
  4706. ------
  4707. ValueError
  4708. If `bins` is not monotonic.
  4709. TypeError
  4710. If the type of the input is complex.
  4711. See Also
  4712. --------
  4713. bincount, histogram, unique, searchsorted
  4714. Notes
  4715. -----
  4716. If values in `x` are such that they fall outside the bin range,
  4717. attempting to index `bins` with the indices that `digitize` returns
  4718. will result in an IndexError.
  4719. .. versionadded:: 1.10.0
  4720. `np.digitize` is implemented in terms of `np.searchsorted`. This means
  4721. that a binary search is used to bin the values, which scales much better
  4722. for larger number of bins than the previous linear search. It also removes
  4723. the requirement for the input array to be 1-dimensional.
  4724. For monotonically _increasing_ `bins`, the following are equivalent::
  4725. np.digitize(x, bins, right=True)
  4726. np.searchsorted(bins, x, side='left')
  4727. Note that as the order of the arguments are reversed, the side must be too.
  4728. The `searchsorted` call is marginally faster, as it does not do any
  4729. monotonicity checks. Perhaps more importantly, it supports all dtypes.
  4730. Examples
  4731. --------
  4732. >>> x = np.array([0.2, 6.4, 3.0, 1.6])
  4733. >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])
  4734. >>> inds = np.digitize(x, bins)
  4735. >>> inds
  4736. array([1, 4, 3, 2])
  4737. >>> for n in range(x.size):
  4738. ... print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]])
  4739. ...
  4740. 0.0 <= 0.2 < 1.0
  4741. 4.0 <= 6.4 < 10.0
  4742. 2.5 <= 3.0 < 4.0
  4743. 1.0 <= 1.6 < 2.5
  4744. >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.])
  4745. >>> bins = np.array([0, 5, 10, 15, 20])
  4746. >>> np.digitize(x,bins,right=True)
  4747. array([1, 2, 3, 4, 4])
  4748. >>> np.digitize(x,bins,right=False)
  4749. array([1, 3, 3, 4, 5])
  4750. """
  4751. x = _nx.asarray(x)
  4752. bins = _nx.asarray(bins)
  4753. # here for compatibility, searchsorted below is happy to take this
  4754. if np.issubdtype(x.dtype, _nx.complexfloating):
  4755. raise TypeError("x may not be complex")
  4756. mono = _monotonicity(bins)
  4757. if mono == 0:
  4758. raise ValueError("bins must be monotonically increasing or decreasing")
  4759. # this is backwards because the arguments below are swapped
  4760. side = 'left' if right else 'right'
  4761. if mono == -1:
  4762. # reverse the bins, and invert the results
  4763. return len(bins) - _nx.searchsorted(bins[::-1], x, side=side)
  4764. else:
  4765. return _nx.searchsorted(bins, x, side=side)