series.py 209 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652
  1. """
  2. Data structure for 1-dimensional cross-sectional and time series data
  3. """
  4. from __future__ import annotations
  5. from collections.abc import (
  6. Hashable,
  7. Iterable,
  8. Mapping,
  9. Sequence,
  10. )
  11. import operator
  12. import sys
  13. from textwrap import dedent
  14. from typing import (
  15. IO,
  16. TYPE_CHECKING,
  17. Any,
  18. Callable,
  19. Literal,
  20. cast,
  21. overload,
  22. )
  23. import warnings
  24. import weakref
  25. import numpy as np
  26. from pandas._config import (
  27. using_copy_on_write,
  28. warn_copy_on_write,
  29. )
  30. from pandas._config.config import _get_option
  31. from pandas._libs import (
  32. lib,
  33. properties,
  34. reshape,
  35. )
  36. from pandas._libs.lib import is_range_indexer
  37. from pandas.compat import PYPY
  38. from pandas.compat._constants import (
  39. REF_COUNT,
  40. WARNING_CHECK_DISABLED,
  41. )
  42. from pandas.compat._optional import import_optional_dependency
  43. from pandas.compat.numpy import function as nv
  44. from pandas.errors import (
  45. ChainedAssignmentError,
  46. InvalidIndexError,
  47. _chained_assignment_method_msg,
  48. _chained_assignment_msg,
  49. _chained_assignment_warning_method_msg,
  50. _chained_assignment_warning_msg,
  51. _check_cacher,
  52. )
  53. from pandas.util._decorators import (
  54. Appender,
  55. Substitution,
  56. deprecate_nonkeyword_arguments,
  57. doc,
  58. )
  59. from pandas.util._exceptions import find_stack_level
  60. from pandas.util._validators import (
  61. validate_ascending,
  62. validate_bool_kwarg,
  63. validate_percentile,
  64. )
  65. from pandas.core.dtypes.astype import astype_is_view
  66. from pandas.core.dtypes.cast import (
  67. LossySetitemError,
  68. construct_1d_arraylike_from_scalar,
  69. find_common_type,
  70. infer_dtype_from,
  71. maybe_box_native,
  72. maybe_cast_pointwise_result,
  73. )
  74. from pandas.core.dtypes.common import (
  75. is_dict_like,
  76. is_integer,
  77. is_iterator,
  78. is_list_like,
  79. is_object_dtype,
  80. is_scalar,
  81. pandas_dtype,
  82. validate_all_hashable,
  83. )
  84. from pandas.core.dtypes.dtypes import (
  85. CategoricalDtype,
  86. ExtensionDtype,
  87. SparseDtype,
  88. )
  89. from pandas.core.dtypes.generic import (
  90. ABCDataFrame,
  91. ABCSeries,
  92. )
  93. from pandas.core.dtypes.inference import is_hashable
  94. from pandas.core.dtypes.missing import (
  95. isna,
  96. na_value_for_dtype,
  97. notna,
  98. remove_na_arraylike,
  99. )
  100. from pandas.core import (
  101. algorithms,
  102. base,
  103. common as com,
  104. missing,
  105. nanops,
  106. ops,
  107. roperator,
  108. )
  109. from pandas.core.accessor import CachedAccessor
  110. from pandas.core.apply import SeriesApply
  111. from pandas.core.arrays import ExtensionArray
  112. from pandas.core.arrays.arrow import (
  113. ListAccessor,
  114. StructAccessor,
  115. )
  116. from pandas.core.arrays.categorical import CategoricalAccessor
  117. from pandas.core.arrays.sparse import SparseAccessor
  118. from pandas.core.arrays.string_ import StringDtype
  119. from pandas.core.construction import (
  120. array as pd_array,
  121. extract_array,
  122. sanitize_array,
  123. )
  124. from pandas.core.generic import (
  125. NDFrame,
  126. make_doc,
  127. )
  128. from pandas.core.indexers import (
  129. disallow_ndim_indexing,
  130. unpack_1tuple,
  131. )
  132. from pandas.core.indexes.accessors import CombinedDatetimelikeProperties
  133. from pandas.core.indexes.api import (
  134. DatetimeIndex,
  135. Index,
  136. MultiIndex,
  137. PeriodIndex,
  138. default_index,
  139. ensure_index,
  140. )
  141. import pandas.core.indexes.base as ibase
  142. from pandas.core.indexes.multi import maybe_droplevels
  143. from pandas.core.indexing import (
  144. check_bool_indexer,
  145. check_dict_or_set_indexers,
  146. )
  147. from pandas.core.internals import (
  148. SingleArrayManager,
  149. SingleBlockManager,
  150. )
  151. from pandas.core.methods import selectn
  152. from pandas.core.shared_docs import _shared_docs
  153. from pandas.core.sorting import (
  154. ensure_key_mapped,
  155. nargsort,
  156. )
  157. from pandas.core.strings.accessor import StringMethods
  158. from pandas.core.tools.datetimes import to_datetime
  159. import pandas.io.formats.format as fmt
  160. from pandas.io.formats.info import (
  161. INFO_DOCSTRING,
  162. SeriesInfo,
  163. series_sub_kwargs,
  164. )
  165. import pandas.plotting
  166. if TYPE_CHECKING:
  167. from pandas._libs.internals import BlockValuesRefs
  168. from pandas._typing import (
  169. AggFuncType,
  170. AnyAll,
  171. AnyArrayLike,
  172. ArrayLike,
  173. Axis,
  174. AxisInt,
  175. CorrelationMethod,
  176. DropKeep,
  177. Dtype,
  178. DtypeObj,
  179. FilePath,
  180. Frequency,
  181. IgnoreRaise,
  182. IndexKeyFunc,
  183. IndexLabel,
  184. Level,
  185. MutableMappingT,
  186. NaPosition,
  187. NumpySorter,
  188. NumpyValueArrayLike,
  189. QuantileInterpolation,
  190. ReindexMethod,
  191. Renamer,
  192. Scalar,
  193. Self,
  194. SingleManager,
  195. SortKind,
  196. StorageOptions,
  197. Suffixes,
  198. ValueKeyFunc,
  199. WriteBuffer,
  200. npt,
  201. )
  202. from pandas.core.frame import DataFrame
  203. from pandas.core.groupby.generic import SeriesGroupBy
  204. __all__ = ["Series"]
  205. _shared_doc_kwargs = {
  206. "axes": "index",
  207. "klass": "Series",
  208. "axes_single_arg": "{0 or 'index'}",
  209. "axis": """axis : {0 or 'index'}
  210. Unused. Parameter needed for compatibility with DataFrame.""",
  211. "inplace": """inplace : bool, default False
  212. If True, performs operation inplace and returns None.""",
  213. "unique": "np.ndarray",
  214. "duplicated": "Series",
  215. "optional_by": "",
  216. "optional_reindex": """
  217. index : array-like, optional
  218. New labels for the index. Preferably an Index object to avoid
  219. duplicating data.
  220. axis : int or str, optional
  221. Unused.""",
  222. }
  223. def _coerce_method(converter):
  224. """
  225. Install the scalar coercion methods.
  226. """
  227. def wrapper(self):
  228. if len(self) == 1:
  229. warnings.warn(
  230. f"Calling {converter.__name__} on a single element Series is "
  231. "deprecated and will raise a TypeError in the future. "
  232. f"Use {converter.__name__}(ser.iloc[0]) instead",
  233. FutureWarning,
  234. stacklevel=find_stack_level(),
  235. )
  236. return converter(self.iloc[0])
  237. raise TypeError(f"cannot convert the series to {converter}")
  238. wrapper.__name__ = f"__{converter.__name__}__"
  239. return wrapper
  240. # ----------------------------------------------------------------------
  241. # Series class
  242. # error: Cannot override final attribute "ndim" (previously declared in base
  243. # class "NDFrame")
  244. # error: Cannot override final attribute "size" (previously declared in base
  245. # class "NDFrame")
  246. # definition in base class "NDFrame"
  247. class Series(base.IndexOpsMixin, NDFrame): # type: ignore[misc]
  248. """
  249. One-dimensional ndarray with axis labels (including time series).
  250. Labels need not be unique but must be a hashable type. The object
  251. supports both integer- and label-based indexing and provides a host of
  252. methods for performing operations involving the index. Statistical
  253. methods from ndarray have been overridden to automatically exclude
  254. missing data (currently represented as NaN).
  255. Operations between Series (+, -, /, \\*, \\*\\*) align values based on their
  256. associated index values-- they need not be the same length. The result
  257. index will be the sorted union of the two indexes.
  258. Parameters
  259. ----------
  260. data : array-like, Iterable, dict, or scalar value
  261. Contains data stored in Series. If data is a dict, argument order is
  262. maintained.
  263. index : array-like or Index (1d)
  264. Values must be hashable and have the same length as `data`.
  265. Non-unique index values are allowed. Will default to
  266. RangeIndex (0, 1, 2, ..., n) if not provided. If data is dict-like
  267. and index is None, then the keys in the data are used as the index. If the
  268. index is not None, the resulting Series is reindexed with the index values.
  269. dtype : str, numpy.dtype, or ExtensionDtype, optional
  270. Data type for the output Series. If not specified, this will be
  271. inferred from `data`.
  272. See the :ref:`user guide <basics.dtypes>` for more usages.
  273. name : Hashable, default None
  274. The name to give to the Series.
  275. copy : bool, default False
  276. Copy input data. Only affects Series or 1d ndarray input. See examples.
  277. Notes
  278. -----
  279. Please reference the :ref:`User Guide <basics.series>` for more information.
  280. Examples
  281. --------
  282. Constructing Series from a dictionary with an Index specified
  283. >>> d = {'a': 1, 'b': 2, 'c': 3}
  284. >>> ser = pd.Series(data=d, index=['a', 'b', 'c'])
  285. >>> ser
  286. a 1
  287. b 2
  288. c 3
  289. dtype: int64
  290. The keys of the dictionary match with the Index values, hence the Index
  291. values have no effect.
  292. >>> d = {'a': 1, 'b': 2, 'c': 3}
  293. >>> ser = pd.Series(data=d, index=['x', 'y', 'z'])
  294. >>> ser
  295. x NaN
  296. y NaN
  297. z NaN
  298. dtype: float64
  299. Note that the Index is first build with the keys from the dictionary.
  300. After this the Series is reindexed with the given Index values, hence we
  301. get all NaN as a result.
  302. Constructing Series from a list with `copy=False`.
  303. >>> r = [1, 2]
  304. >>> ser = pd.Series(r, copy=False)
  305. >>> ser.iloc[0] = 999
  306. >>> r
  307. [1, 2]
  308. >>> ser
  309. 0 999
  310. 1 2
  311. dtype: int64
  312. Due to input data type the Series has a `copy` of
  313. the original data even though `copy=False`, so
  314. the data is unchanged.
  315. Constructing Series from a 1d ndarray with `copy=False`.
  316. >>> r = np.array([1, 2])
  317. >>> ser = pd.Series(r, copy=False)
  318. >>> ser.iloc[0] = 999
  319. >>> r
  320. array([999, 2])
  321. >>> ser
  322. 0 999
  323. 1 2
  324. dtype: int64
  325. Due to input data type the Series has a `view` on
  326. the original data, so
  327. the data is changed as well.
  328. """
  329. _typ = "series"
  330. _HANDLED_TYPES = (Index, ExtensionArray, np.ndarray)
  331. _name: Hashable
  332. _metadata: list[str] = ["_name"]
  333. _internal_names_set = {"index", "name"} | NDFrame._internal_names_set
  334. _accessors = {"dt", "cat", "str", "sparse"}
  335. _hidden_attrs = (
  336. base.IndexOpsMixin._hidden_attrs | NDFrame._hidden_attrs | frozenset([])
  337. )
  338. # similar to __array_priority__, positions Series after DataFrame
  339. # but before Index and ExtensionArray. Should NOT be overridden by subclasses.
  340. __pandas_priority__ = 3000
  341. # Override cache_readonly bc Series is mutable
  342. # error: Incompatible types in assignment (expression has type "property",
  343. # base class "IndexOpsMixin" defined the type as "Callable[[IndexOpsMixin], bool]")
  344. hasnans = property( # type: ignore[assignment]
  345. # error: "Callable[[IndexOpsMixin], bool]" has no attribute "fget"
  346. base.IndexOpsMixin.hasnans.fget, # type: ignore[attr-defined]
  347. doc=base.IndexOpsMixin.hasnans.__doc__,
  348. )
  349. _mgr: SingleManager
  350. # ----------------------------------------------------------------------
  351. # Constructors
  352. def __init__(
  353. self,
  354. data=None,
  355. index=None,
  356. dtype: Dtype | None = None,
  357. name=None,
  358. copy: bool | None = None,
  359. fastpath: bool | lib.NoDefault = lib.no_default,
  360. ) -> None:
  361. if fastpath is not lib.no_default:
  362. warnings.warn(
  363. "The 'fastpath' keyword in pd.Series is deprecated and will "
  364. "be removed in a future version.",
  365. DeprecationWarning,
  366. stacklevel=find_stack_level(),
  367. )
  368. else:
  369. fastpath = False
  370. allow_mgr = False
  371. if (
  372. isinstance(data, (SingleBlockManager, SingleArrayManager))
  373. and index is None
  374. and dtype is None
  375. and (copy is False or copy is None)
  376. ):
  377. if not allow_mgr:
  378. # GH#52419
  379. warnings.warn(
  380. f"Passing a {type(data).__name__} to {type(self).__name__} "
  381. "is deprecated and will raise in a future version. "
  382. "Use public APIs instead.",
  383. DeprecationWarning,
  384. stacklevel=2,
  385. )
  386. if using_copy_on_write():
  387. data = data.copy(deep=False)
  388. # GH#33357 called with just the SingleBlockManager
  389. NDFrame.__init__(self, data)
  390. if fastpath:
  391. # e.g. from _box_col_values, skip validation of name
  392. object.__setattr__(self, "_name", name)
  393. else:
  394. self.name = name
  395. return
  396. is_pandas_object = isinstance(data, (Series, Index, ExtensionArray))
  397. data_dtype = getattr(data, "dtype", None)
  398. original_dtype = dtype
  399. if isinstance(data, (ExtensionArray, np.ndarray)):
  400. if copy is not False and using_copy_on_write():
  401. if dtype is None or astype_is_view(data.dtype, pandas_dtype(dtype)):
  402. data = data.copy()
  403. if copy is None:
  404. copy = False
  405. # we are called internally, so short-circuit
  406. if fastpath:
  407. # data is a ndarray, index is defined
  408. if not isinstance(data, (SingleBlockManager, SingleArrayManager)):
  409. manager = _get_option("mode.data_manager", silent=True)
  410. if manager == "block":
  411. data = SingleBlockManager.from_array(data, index)
  412. elif manager == "array":
  413. data = SingleArrayManager.from_array(data, index)
  414. allow_mgr = True
  415. elif using_copy_on_write() and not copy:
  416. data = data.copy(deep=False)
  417. if not allow_mgr:
  418. warnings.warn(
  419. f"Passing a {type(data).__name__} to {type(self).__name__} "
  420. "is deprecated and will raise in a future version. "
  421. "Use public APIs instead.",
  422. DeprecationWarning,
  423. stacklevel=2,
  424. )
  425. if copy:
  426. data = data.copy()
  427. # skips validation of the name
  428. object.__setattr__(self, "_name", name)
  429. NDFrame.__init__(self, data)
  430. return
  431. if isinstance(data, SingleBlockManager) and using_copy_on_write() and not copy:
  432. data = data.copy(deep=False)
  433. if not allow_mgr:
  434. warnings.warn(
  435. f"Passing a {type(data).__name__} to {type(self).__name__} "
  436. "is deprecated and will raise in a future version. "
  437. "Use public APIs instead.",
  438. DeprecationWarning,
  439. stacklevel=2,
  440. )
  441. name = ibase.maybe_extract_name(name, data, type(self))
  442. if index is not None:
  443. index = ensure_index(index)
  444. if dtype is not None:
  445. dtype = self._validate_dtype(dtype)
  446. if data is None:
  447. index = index if index is not None else default_index(0)
  448. if len(index) or dtype is not None:
  449. data = na_value_for_dtype(pandas_dtype(dtype), compat=False)
  450. else:
  451. data = []
  452. if isinstance(data, MultiIndex):
  453. raise NotImplementedError(
  454. "initializing a Series from a MultiIndex is not supported"
  455. )
  456. refs = None
  457. if isinstance(data, Index):
  458. if dtype is not None:
  459. data = data.astype(dtype, copy=False)
  460. if using_copy_on_write():
  461. refs = data._references
  462. data = data._values
  463. else:
  464. # GH#24096 we need to ensure the index remains immutable
  465. data = data._values.copy()
  466. copy = False
  467. elif isinstance(data, np.ndarray):
  468. if len(data.dtype):
  469. # GH#13296 we are dealing with a compound dtype, which
  470. # should be treated as 2D
  471. raise ValueError(
  472. "Cannot construct a Series from an ndarray with "
  473. "compound dtype. Use DataFrame instead."
  474. )
  475. elif isinstance(data, Series):
  476. if index is None:
  477. index = data.index
  478. data = data._mgr.copy(deep=False)
  479. else:
  480. data = data.reindex(index, copy=copy)
  481. copy = False
  482. data = data._mgr
  483. elif isinstance(data, Mapping):
  484. data, index = self._init_dict(data, index, dtype)
  485. dtype = None
  486. copy = False
  487. elif isinstance(data, (SingleBlockManager, SingleArrayManager)):
  488. if index is None:
  489. index = data.index
  490. elif not data.index.equals(index) or copy:
  491. # GH#19275 SingleBlockManager input should only be called
  492. # internally
  493. raise AssertionError(
  494. "Cannot pass both SingleBlockManager "
  495. "`data` argument and a different "
  496. "`index` argument. `copy` must be False."
  497. )
  498. if not allow_mgr:
  499. warnings.warn(
  500. f"Passing a {type(data).__name__} to {type(self).__name__} "
  501. "is deprecated and will raise in a future version. "
  502. "Use public APIs instead.",
  503. DeprecationWarning,
  504. stacklevel=2,
  505. )
  506. allow_mgr = True
  507. elif isinstance(data, ExtensionArray):
  508. pass
  509. else:
  510. data = com.maybe_iterable_to_list(data)
  511. if is_list_like(data) and not len(data) and dtype is None:
  512. # GH 29405: Pre-2.0, this defaulted to float.
  513. dtype = np.dtype(object)
  514. if index is None:
  515. if not is_list_like(data):
  516. data = [data]
  517. index = default_index(len(data))
  518. elif is_list_like(data):
  519. com.require_length_match(data, index)
  520. # create/copy the manager
  521. if isinstance(data, (SingleBlockManager, SingleArrayManager)):
  522. if dtype is not None:
  523. data = data.astype(dtype=dtype, errors="ignore", copy=copy)
  524. elif copy:
  525. data = data.copy()
  526. else:
  527. data = sanitize_array(data, index, dtype, copy)
  528. manager = _get_option("mode.data_manager", silent=True)
  529. if manager == "block":
  530. data = SingleBlockManager.from_array(data, index, refs=refs)
  531. elif manager == "array":
  532. data = SingleArrayManager.from_array(data, index)
  533. NDFrame.__init__(self, data)
  534. self.name = name
  535. self._set_axis(0, index)
  536. if original_dtype is None and is_pandas_object and data_dtype == np.object_:
  537. if self.dtype != data_dtype:
  538. warnings.warn(
  539. "Dtype inference on a pandas object "
  540. "(Series, Index, ExtensionArray) is deprecated. The Series "
  541. "constructor will keep the original dtype in the future. "
  542. "Call `infer_objects` on the result to get the old behavior.",
  543. FutureWarning,
  544. stacklevel=find_stack_level(),
  545. )
  546. def _init_dict(
  547. self, data: Mapping, index: Index | None = None, dtype: DtypeObj | None = None
  548. ):
  549. """
  550. Derive the "_mgr" and "index" attributes of a new Series from a
  551. dictionary input.
  552. Parameters
  553. ----------
  554. data : dict or dict-like
  555. Data used to populate the new Series.
  556. index : Index or None, default None
  557. Index for the new Series: if None, use dict keys.
  558. dtype : np.dtype, ExtensionDtype, or None, default None
  559. The dtype for the new Series: if None, infer from data.
  560. Returns
  561. -------
  562. _data : BlockManager for the new Series
  563. index : index for the new Series
  564. """
  565. keys: Index | tuple
  566. # Looking for NaN in dict doesn't work ({np.nan : 1}[float('nan')]
  567. # raises KeyError), so we iterate the entire dict, and align
  568. if data:
  569. # GH:34717, issue was using zip to extract key and values from data.
  570. # using generators in effects the performance.
  571. # Below is the new way of extracting the keys and values
  572. keys = tuple(data.keys())
  573. values = list(data.values()) # Generating list of values- faster way
  574. elif index is not None:
  575. # fastpath for Series(data=None). Just use broadcasting a scalar
  576. # instead of reindexing.
  577. if len(index) or dtype is not None:
  578. values = na_value_for_dtype(pandas_dtype(dtype), compat=False)
  579. else:
  580. values = []
  581. keys = index
  582. else:
  583. keys, values = default_index(0), []
  584. # Input is now list-like, so rely on "standard" construction:
  585. s = Series(values, index=keys, dtype=dtype)
  586. # Now we just make sure the order is respected, if any
  587. if data and index is not None:
  588. s = s.reindex(index, copy=False)
  589. return s._mgr, s.index
  590. # ----------------------------------------------------------------------
  591. @property
  592. def _constructor(self) -> Callable[..., Series]:
  593. return Series
  594. def _constructor_from_mgr(self, mgr, axes):
  595. ser = Series._from_mgr(mgr, axes=axes)
  596. ser._name = None # caller is responsible for setting real name
  597. if type(self) is Series:
  598. # This would also work `if self._constructor is Series`, but
  599. # this check is slightly faster, benefiting the most-common case.
  600. return ser
  601. # We assume that the subclass __init__ knows how to handle a
  602. # pd.Series object.
  603. return self._constructor(ser)
  604. @property
  605. def _constructor_expanddim(self) -> Callable[..., DataFrame]:
  606. """
  607. Used when a manipulation result has one higher dimension as the
  608. original, such as Series.to_frame()
  609. """
  610. from pandas.core.frame import DataFrame
  611. return DataFrame
  612. def _constructor_expanddim_from_mgr(self, mgr, axes):
  613. from pandas.core.frame import DataFrame
  614. df = DataFrame._from_mgr(mgr, axes=mgr.axes)
  615. if type(self) is Series:
  616. # This would also work `if self._constructor_expanddim is DataFrame`,
  617. # but this check is slightly faster, benefiting the most-common case.
  618. return df
  619. # We assume that the subclass __init__ knows how to handle a
  620. # pd.DataFrame object.
  621. return self._constructor_expanddim(df)
  622. # types
  623. @property
  624. def _can_hold_na(self) -> bool:
  625. return self._mgr._can_hold_na
  626. # ndarray compatibility
  627. @property
  628. def dtype(self) -> DtypeObj:
  629. """
  630. Return the dtype object of the underlying data.
  631. Examples
  632. --------
  633. >>> s = pd.Series([1, 2, 3])
  634. >>> s.dtype
  635. dtype('int64')
  636. """
  637. return self._mgr.dtype
  638. @property
  639. def dtypes(self) -> DtypeObj:
  640. """
  641. Return the dtype object of the underlying data.
  642. Examples
  643. --------
  644. >>> s = pd.Series([1, 2, 3])
  645. >>> s.dtypes
  646. dtype('int64')
  647. """
  648. # DataFrame compatibility
  649. return self.dtype
  650. @property
  651. def name(self) -> Hashable:
  652. """
  653. Return the name of the Series.
  654. The name of a Series becomes its index or column name if it is used
  655. to form a DataFrame. It is also used whenever displaying the Series
  656. using the interpreter.
  657. Returns
  658. -------
  659. label (hashable object)
  660. The name of the Series, also the column name if part of a DataFrame.
  661. See Also
  662. --------
  663. Series.rename : Sets the Series name when given a scalar input.
  664. Index.name : Corresponding Index property.
  665. Examples
  666. --------
  667. The Series name can be set initially when calling the constructor.
  668. >>> s = pd.Series([1, 2, 3], dtype=np.int64, name='Numbers')
  669. >>> s
  670. 0 1
  671. 1 2
  672. 2 3
  673. Name: Numbers, dtype: int64
  674. >>> s.name = "Integers"
  675. >>> s
  676. 0 1
  677. 1 2
  678. 2 3
  679. Name: Integers, dtype: int64
  680. The name of a Series within a DataFrame is its column name.
  681. >>> df = pd.DataFrame([[1, 2], [3, 4], [5, 6]],
  682. ... columns=["Odd Numbers", "Even Numbers"])
  683. >>> df
  684. Odd Numbers Even Numbers
  685. 0 1 2
  686. 1 3 4
  687. 2 5 6
  688. >>> df["Even Numbers"].name
  689. 'Even Numbers'
  690. """
  691. return self._name
  692. @name.setter
  693. def name(self, value: Hashable) -> None:
  694. validate_all_hashable(value, error_name=f"{type(self).__name__}.name")
  695. object.__setattr__(self, "_name", value)
  696. @property
  697. def values(self):
  698. """
  699. Return Series as ndarray or ndarray-like depending on the dtype.
  700. .. warning::
  701. We recommend using :attr:`Series.array` or
  702. :meth:`Series.to_numpy`, depending on whether you need
  703. a reference to the underlying data or a NumPy array.
  704. Returns
  705. -------
  706. numpy.ndarray or ndarray-like
  707. See Also
  708. --------
  709. Series.array : Reference to the underlying data.
  710. Series.to_numpy : A NumPy array representing the underlying data.
  711. Examples
  712. --------
  713. >>> pd.Series([1, 2, 3]).values
  714. array([1, 2, 3])
  715. >>> pd.Series(list('aabc')).values
  716. array(['a', 'a', 'b', 'c'], dtype=object)
  717. >>> pd.Series(list('aabc')).astype('category').values
  718. ['a', 'a', 'b', 'c']
  719. Categories (3, object): ['a', 'b', 'c']
  720. Timezone aware datetime data is converted to UTC:
  721. >>> pd.Series(pd.date_range('20130101', periods=3,
  722. ... tz='US/Eastern')).values
  723. array(['2013-01-01T05:00:00.000000000',
  724. '2013-01-02T05:00:00.000000000',
  725. '2013-01-03T05:00:00.000000000'], dtype='datetime64[ns]')
  726. """
  727. return self._mgr.external_values()
  728. @property
  729. def _values(self):
  730. """
  731. Return the internal repr of this data (defined by Block.interval_values).
  732. This are the values as stored in the Block (ndarray or ExtensionArray
  733. depending on the Block class), with datetime64[ns] and timedelta64[ns]
  734. wrapped in ExtensionArrays to match Index._values behavior.
  735. Differs from the public ``.values`` for certain data types, because of
  736. historical backwards compatibility of the public attribute (e.g. period
  737. returns object ndarray and datetimetz a datetime64[ns] ndarray for
  738. ``.values`` while it returns an ExtensionArray for ``._values`` in those
  739. cases).
  740. Differs from ``.array`` in that this still returns the numpy array if
  741. the Block is backed by a numpy array (except for datetime64 and
  742. timedelta64 dtypes), while ``.array`` ensures to always return an
  743. ExtensionArray.
  744. Overview:
  745. dtype | values | _values | array |
  746. ----------- | ------------- | ------------- | --------------------- |
  747. Numeric | ndarray | ndarray | NumpyExtensionArray |
  748. Category | Categorical | Categorical | Categorical |
  749. dt64[ns] | ndarray[M8ns] | DatetimeArray | DatetimeArray |
  750. dt64[ns tz] | ndarray[M8ns] | DatetimeArray | DatetimeArray |
  751. td64[ns] | ndarray[m8ns] | TimedeltaArray| TimedeltaArray |
  752. Period | ndarray[obj] | PeriodArray | PeriodArray |
  753. Nullable | EA | EA | EA |
  754. """
  755. return self._mgr.internal_values()
  756. @property
  757. def _references(self) -> BlockValuesRefs | None:
  758. if isinstance(self._mgr, SingleArrayManager):
  759. return None
  760. return self._mgr._block.refs
  761. # error: Decorated property not supported
  762. @Appender(base.IndexOpsMixin.array.__doc__) # type: ignore[misc]
  763. @property
  764. def array(self) -> ExtensionArray:
  765. return self._mgr.array_values()
  766. # ops
  767. def ravel(self, order: str = "C") -> ArrayLike:
  768. """
  769. Return the flattened underlying data as an ndarray or ExtensionArray.
  770. .. deprecated:: 2.2.0
  771. Series.ravel is deprecated. The underlying array is already 1D, so
  772. ravel is not necessary. Use :meth:`to_numpy` for conversion to a numpy
  773. array instead.
  774. Returns
  775. -------
  776. numpy.ndarray or ExtensionArray
  777. Flattened data of the Series.
  778. See Also
  779. --------
  780. numpy.ndarray.ravel : Return a flattened array.
  781. Examples
  782. --------
  783. >>> s = pd.Series([1, 2, 3])
  784. >>> s.ravel() # doctest: +SKIP
  785. array([1, 2, 3])
  786. """
  787. warnings.warn(
  788. "Series.ravel is deprecated. The underlying array is already 1D, so "
  789. "ravel is not necessary. Use `to_numpy()` for conversion to a numpy "
  790. "array instead.",
  791. FutureWarning,
  792. stacklevel=2,
  793. )
  794. arr = self._values.ravel(order=order)
  795. if isinstance(arr, np.ndarray) and using_copy_on_write():
  796. arr.flags.writeable = False
  797. return arr
  798. def __len__(self) -> int:
  799. """
  800. Return the length of the Series.
  801. """
  802. return len(self._mgr)
  803. def view(self, dtype: Dtype | None = None) -> Series:
  804. """
  805. Create a new view of the Series.
  806. .. deprecated:: 2.2.0
  807. ``Series.view`` is deprecated and will be removed in a future version.
  808. Use :meth:`Series.astype` as an alternative to change the dtype.
  809. This function will return a new Series with a view of the same
  810. underlying values in memory, optionally reinterpreted with a new data
  811. type. The new data type must preserve the same size in bytes as to not
  812. cause index misalignment.
  813. Parameters
  814. ----------
  815. dtype : data type
  816. Data type object or one of their string representations.
  817. Returns
  818. -------
  819. Series
  820. A new Series object as a view of the same data in memory.
  821. See Also
  822. --------
  823. numpy.ndarray.view : Equivalent numpy function to create a new view of
  824. the same data in memory.
  825. Notes
  826. -----
  827. Series are instantiated with ``dtype=float64`` by default. While
  828. ``numpy.ndarray.view()`` will return a view with the same data type as
  829. the original array, ``Series.view()`` (without specified dtype)
  830. will try using ``float64`` and may fail if the original data type size
  831. in bytes is not the same.
  832. Examples
  833. --------
  834. Use ``astype`` to change the dtype instead.
  835. """
  836. warnings.warn(
  837. "Series.view is deprecated and will be removed in a future version. "
  838. "Use ``astype`` as an alternative to change the dtype.",
  839. FutureWarning,
  840. stacklevel=2,
  841. )
  842. # self.array instead of self._values so we piggyback on NumpyExtensionArray
  843. # implementation
  844. res_values = self.array.view(dtype)
  845. res_ser = self._constructor(res_values, index=self.index, copy=False)
  846. if isinstance(res_ser._mgr, SingleBlockManager):
  847. blk = res_ser._mgr._block
  848. blk.refs = cast("BlockValuesRefs", self._references)
  849. blk.refs.add_reference(blk)
  850. return res_ser.__finalize__(self, method="view")
  851. # ----------------------------------------------------------------------
  852. # NDArray Compat
  853. def __array__(
  854. self, dtype: npt.DTypeLike | None = None, copy: bool | None = None
  855. ) -> np.ndarray:
  856. """
  857. Return the values as a NumPy array.
  858. Users should not call this directly. Rather, it is invoked by
  859. :func:`numpy.array` and :func:`numpy.asarray`.
  860. Parameters
  861. ----------
  862. dtype : str or numpy.dtype, optional
  863. The dtype to use for the resulting NumPy array. By default,
  864. the dtype is inferred from the data.
  865. copy : bool or None, optional
  866. See :func:`numpy.asarray`.
  867. Returns
  868. -------
  869. numpy.ndarray
  870. The values in the series converted to a :class:`numpy.ndarray`
  871. with the specified `dtype`.
  872. See Also
  873. --------
  874. array : Create a new array from data.
  875. Series.array : Zero-copy view to the array backing the Series.
  876. Series.to_numpy : Series method for similar behavior.
  877. Examples
  878. --------
  879. >>> ser = pd.Series([1, 2, 3])
  880. >>> np.asarray(ser)
  881. array([1, 2, 3])
  882. For timezone-aware data, the timezones may be retained with
  883. ``dtype='object'``
  884. >>> tzser = pd.Series(pd.date_range('2000', periods=2, tz="CET"))
  885. >>> np.asarray(tzser, dtype="object")
  886. array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
  887. Timestamp('2000-01-02 00:00:00+0100', tz='CET')],
  888. dtype=object)
  889. Or the values may be localized to UTC and the tzinfo discarded with
  890. ``dtype='datetime64[ns]'``
  891. >>> np.asarray(tzser, dtype="datetime64[ns]") # doctest: +ELLIPSIS
  892. array(['1999-12-31T23:00:00.000000000', ...],
  893. dtype='datetime64[ns]')
  894. """
  895. values = self._values
  896. if copy is None:
  897. # Note: branch avoids `copy=None` for NumPy 1.x support
  898. arr = np.asarray(values, dtype=dtype)
  899. else:
  900. arr = np.array(values, dtype=dtype, copy=copy)
  901. if copy is True:
  902. return arr
  903. if using_copy_on_write() and (
  904. copy is False or astype_is_view(values.dtype, arr.dtype)
  905. ):
  906. arr = arr.view()
  907. arr.flags.writeable = False
  908. return arr
  909. # ----------------------------------------------------------------------
  910. def __column_consortium_standard__(self, *, api_version: str | None = None) -> Any:
  911. """
  912. Provide entry point to the Consortium DataFrame Standard API.
  913. This is developed and maintained outside of pandas.
  914. Please report any issues to https://github.com/data-apis/dataframe-api-compat.
  915. """
  916. dataframe_api_compat = import_optional_dependency("dataframe_api_compat")
  917. return (
  918. dataframe_api_compat.pandas_standard.convert_to_standard_compliant_column(
  919. self, api_version=api_version
  920. )
  921. )
  922. # ----------------------------------------------------------------------
  923. # Unary Methods
  924. # coercion
  925. __float__ = _coerce_method(float)
  926. __int__ = _coerce_method(int)
  927. # ----------------------------------------------------------------------
  928. # indexers
  929. @property
  930. def axes(self) -> list[Index]:
  931. """
  932. Return a list of the row axis labels.
  933. """
  934. return [self.index]
  935. # ----------------------------------------------------------------------
  936. # Indexing Methods
  937. def _ixs(self, i: int, axis: AxisInt = 0) -> Any:
  938. """
  939. Return the i-th value or values in the Series by location.
  940. Parameters
  941. ----------
  942. i : int
  943. Returns
  944. -------
  945. scalar
  946. """
  947. return self._values[i]
  948. def _slice(self, slobj: slice, axis: AxisInt = 0) -> Series:
  949. # axis kwarg is retained for compat with NDFrame method
  950. # _slice is *always* positional
  951. mgr = self._mgr.get_slice(slobj, axis=axis)
  952. out = self._constructor_from_mgr(mgr, axes=mgr.axes)
  953. out._name = self._name
  954. return out.__finalize__(self)
  955. def __getitem__(self, key):
  956. check_dict_or_set_indexers(key)
  957. key = com.apply_if_callable(key, self)
  958. if key is Ellipsis:
  959. if using_copy_on_write() or warn_copy_on_write():
  960. return self.copy(deep=False)
  961. return self
  962. key_is_scalar = is_scalar(key)
  963. if isinstance(key, (list, tuple)):
  964. key = unpack_1tuple(key)
  965. if is_integer(key) and self.index._should_fallback_to_positional:
  966. warnings.warn(
  967. # GH#50617
  968. "Series.__getitem__ treating keys as positions is deprecated. "
  969. "In a future version, integer keys will always be treated "
  970. "as labels (consistent with DataFrame behavior). To access "
  971. "a value by position, use `ser.iloc[pos]`",
  972. FutureWarning,
  973. stacklevel=find_stack_level(),
  974. )
  975. return self._values[key]
  976. elif key_is_scalar:
  977. return self._get_value(key)
  978. # Convert generator to list before going through hashable part
  979. # (We will iterate through the generator there to check for slices)
  980. if is_iterator(key):
  981. key = list(key)
  982. if is_hashable(key) and not isinstance(key, slice):
  983. # Otherwise index.get_value will raise InvalidIndexError
  984. try:
  985. # For labels that don't resolve as scalars like tuples and frozensets
  986. result = self._get_value(key)
  987. return result
  988. except (KeyError, TypeError, InvalidIndexError):
  989. # InvalidIndexError for e.g. generator
  990. # see test_series_getitem_corner_generator
  991. if isinstance(key, tuple) and isinstance(self.index, MultiIndex):
  992. # We still have the corner case where a tuple is a key
  993. # in the first level of our MultiIndex
  994. return self._get_values_tuple(key)
  995. if isinstance(key, slice):
  996. # Do slice check before somewhat-costly is_bool_indexer
  997. return self._getitem_slice(key)
  998. if com.is_bool_indexer(key):
  999. key = check_bool_indexer(self.index, key)
  1000. key = np.asarray(key, dtype=bool)
  1001. return self._get_rows_with_mask(key)
  1002. return self._get_with(key)
  1003. def _get_with(self, key):
  1004. # other: fancy integer or otherwise
  1005. if isinstance(key, ABCDataFrame):
  1006. raise TypeError(
  1007. "Indexing a Series with DataFrame is not "
  1008. "supported, use the appropriate DataFrame column"
  1009. )
  1010. elif isinstance(key, tuple):
  1011. return self._get_values_tuple(key)
  1012. elif not is_list_like(key):
  1013. # e.g. scalars that aren't recognized by lib.is_scalar, GH#32684
  1014. return self.loc[key]
  1015. if not isinstance(key, (list, np.ndarray, ExtensionArray, Series, Index)):
  1016. key = list(key)
  1017. key_type = lib.infer_dtype(key, skipna=False)
  1018. # Note: The key_type == "boolean" case should be caught by the
  1019. # com.is_bool_indexer check in __getitem__
  1020. if key_type == "integer":
  1021. # We need to decide whether to treat this as a positional indexer
  1022. # (i.e. self.iloc) or label-based (i.e. self.loc)
  1023. if not self.index._should_fallback_to_positional:
  1024. return self.loc[key]
  1025. else:
  1026. warnings.warn(
  1027. # GH#50617
  1028. "Series.__getitem__ treating keys as positions is deprecated. "
  1029. "In a future version, integer keys will always be treated "
  1030. "as labels (consistent with DataFrame behavior). To access "
  1031. "a value by position, use `ser.iloc[pos]`",
  1032. FutureWarning,
  1033. stacklevel=find_stack_level(),
  1034. )
  1035. return self.iloc[key]
  1036. # handle the dup indexing case GH#4246
  1037. return self.loc[key]
  1038. def _get_values_tuple(self, key: tuple):
  1039. # mpl hackaround
  1040. if com.any_none(*key):
  1041. # mpl compat if we look up e.g. ser[:, np.newaxis];
  1042. # see tests.series.timeseries.test_mpl_compat_hack
  1043. # the asarray is needed to avoid returning a 2D DatetimeArray
  1044. result = np.asarray(self._values[key])
  1045. disallow_ndim_indexing(result)
  1046. return result
  1047. if not isinstance(self.index, MultiIndex):
  1048. raise KeyError("key of type tuple not found and not a MultiIndex")
  1049. # If key is contained, would have returned by now
  1050. indexer, new_index = self.index.get_loc_level(key)
  1051. new_ser = self._constructor(self._values[indexer], index=new_index, copy=False)
  1052. if isinstance(indexer, slice):
  1053. new_ser._mgr.add_references(self._mgr) # type: ignore[arg-type]
  1054. return new_ser.__finalize__(self)
  1055. def _get_rows_with_mask(self, indexer: npt.NDArray[np.bool_]) -> Series:
  1056. new_mgr = self._mgr.get_rows_with_mask(indexer)
  1057. return self._constructor_from_mgr(new_mgr, axes=new_mgr.axes).__finalize__(self)
  1058. def _get_value(self, label, takeable: bool = False):
  1059. """
  1060. Quickly retrieve single value at passed index label.
  1061. Parameters
  1062. ----------
  1063. label : object
  1064. takeable : interpret the index as indexers, default False
  1065. Returns
  1066. -------
  1067. scalar value
  1068. """
  1069. if takeable:
  1070. return self._values[label]
  1071. # Similar to Index.get_value, but we do not fall back to positional
  1072. loc = self.index.get_loc(label)
  1073. if is_integer(loc):
  1074. return self._values[loc]
  1075. if isinstance(self.index, MultiIndex):
  1076. mi = self.index
  1077. new_values = self._values[loc]
  1078. if len(new_values) == 1 and mi.nlevels == 1:
  1079. # If more than one level left, we can not return a scalar
  1080. return new_values[0]
  1081. new_index = mi[loc]
  1082. new_index = maybe_droplevels(new_index, label)
  1083. new_ser = self._constructor(
  1084. new_values, index=new_index, name=self.name, copy=False
  1085. )
  1086. if isinstance(loc, slice):
  1087. new_ser._mgr.add_references(self._mgr) # type: ignore[arg-type]
  1088. return new_ser.__finalize__(self)
  1089. else:
  1090. return self.iloc[loc]
  1091. def __setitem__(self, key, value) -> None:
  1092. warn = True
  1093. if not PYPY and not WARNING_CHECK_DISABLED and using_copy_on_write():
  1094. if sys.getrefcount(self) <= 3:
  1095. warnings.warn(
  1096. _chained_assignment_msg, ChainedAssignmentError, stacklevel=2
  1097. )
  1098. elif not PYPY and not WARNING_CHECK_DISABLED and not using_copy_on_write():
  1099. ctr = sys.getrefcount(self)
  1100. ref_count = 3
  1101. if not warn_copy_on_write() and _check_cacher(self):
  1102. # see https://github.com/pandas-dev/pandas/pull/56060#discussion_r1399245221
  1103. ref_count += 1
  1104. if ctr <= ref_count and (
  1105. warn_copy_on_write()
  1106. or (
  1107. not warn_copy_on_write()
  1108. and self._mgr.blocks[0].refs.has_reference() # type: ignore[union-attr]
  1109. )
  1110. ):
  1111. warn = False
  1112. warnings.warn(
  1113. _chained_assignment_warning_msg, FutureWarning, stacklevel=2
  1114. )
  1115. check_dict_or_set_indexers(key)
  1116. key = com.apply_if_callable(key, self)
  1117. cacher_needs_updating = self._check_is_chained_assignment_possible()
  1118. if key is Ellipsis:
  1119. key = slice(None)
  1120. if isinstance(key, slice):
  1121. indexer = self.index._convert_slice_indexer(key, kind="getitem")
  1122. return self._set_values(indexer, value, warn=warn)
  1123. try:
  1124. self._set_with_engine(key, value, warn=warn)
  1125. except KeyError:
  1126. # We have a scalar (or for MultiIndex or object-dtype, scalar-like)
  1127. # key that is not present in self.index.
  1128. if is_integer(key):
  1129. if not self.index._should_fallback_to_positional:
  1130. # GH#33469
  1131. self.loc[key] = value
  1132. else:
  1133. # positional setter
  1134. # can't use _mgr.setitem_inplace yet bc could have *both*
  1135. # KeyError and then ValueError, xref GH#45070
  1136. warnings.warn(
  1137. # GH#50617
  1138. "Series.__setitem__ treating keys as positions is deprecated. "
  1139. "In a future version, integer keys will always be treated "
  1140. "as labels (consistent with DataFrame behavior). To set "
  1141. "a value by position, use `ser.iloc[pos] = value`",
  1142. FutureWarning,
  1143. stacklevel=find_stack_level(),
  1144. )
  1145. self._set_values(key, value)
  1146. else:
  1147. # GH#12862 adding a new key to the Series
  1148. self.loc[key] = value
  1149. except (TypeError, ValueError, LossySetitemError):
  1150. # The key was OK, but we cannot set the value losslessly
  1151. indexer = self.index.get_loc(key)
  1152. self._set_values(indexer, value)
  1153. except InvalidIndexError as err:
  1154. if isinstance(key, tuple) and not isinstance(self.index, MultiIndex):
  1155. # cases with MultiIndex don't get here bc they raise KeyError
  1156. # e.g. test_basic_getitem_setitem_corner
  1157. raise KeyError(
  1158. "key of type tuple not found and not a MultiIndex"
  1159. ) from err
  1160. if com.is_bool_indexer(key):
  1161. key = check_bool_indexer(self.index, key)
  1162. key = np.asarray(key, dtype=bool)
  1163. if (
  1164. is_list_like(value)
  1165. and len(value) != len(self)
  1166. and not isinstance(value, Series)
  1167. and not is_object_dtype(self.dtype)
  1168. ):
  1169. # Series will be reindexed to have matching length inside
  1170. # _where call below
  1171. # GH#44265
  1172. indexer = key.nonzero()[0]
  1173. self._set_values(indexer, value)
  1174. return
  1175. # otherwise with listlike other we interpret series[mask] = other
  1176. # as series[mask] = other[mask]
  1177. try:
  1178. self._where(~key, value, inplace=True, warn=warn)
  1179. except InvalidIndexError:
  1180. # test_where_dups
  1181. self.iloc[key] = value
  1182. return
  1183. else:
  1184. self._set_with(key, value, warn=warn)
  1185. if cacher_needs_updating:
  1186. self._maybe_update_cacher(inplace=True)
  1187. def _set_with_engine(self, key, value, warn: bool = True) -> None:
  1188. loc = self.index.get_loc(key)
  1189. # this is equivalent to self._values[key] = value
  1190. self._mgr.setitem_inplace(loc, value, warn=warn)
  1191. def _set_with(self, key, value, warn: bool = True) -> None:
  1192. # We got here via exception-handling off of InvalidIndexError, so
  1193. # key should always be listlike at this point.
  1194. assert not isinstance(key, tuple)
  1195. if is_iterator(key):
  1196. # Without this, the call to infer_dtype will consume the generator
  1197. key = list(key)
  1198. if not self.index._should_fallback_to_positional:
  1199. # Regardless of the key type, we're treating it as labels
  1200. self._set_labels(key, value, warn=warn)
  1201. else:
  1202. # Note: key_type == "boolean" should not occur because that
  1203. # should be caught by the is_bool_indexer check in __setitem__
  1204. key_type = lib.infer_dtype(key, skipna=False)
  1205. if key_type == "integer":
  1206. warnings.warn(
  1207. # GH#50617
  1208. "Series.__setitem__ treating keys as positions is deprecated. "
  1209. "In a future version, integer keys will always be treated "
  1210. "as labels (consistent with DataFrame behavior). To set "
  1211. "a value by position, use `ser.iloc[pos] = value`",
  1212. FutureWarning,
  1213. stacklevel=find_stack_level(),
  1214. )
  1215. self._set_values(key, value, warn=warn)
  1216. else:
  1217. self._set_labels(key, value, warn=warn)
  1218. def _set_labels(self, key, value, warn: bool = True) -> None:
  1219. key = com.asarray_tuplesafe(key)
  1220. indexer: np.ndarray = self.index.get_indexer(key)
  1221. mask = indexer == -1
  1222. if mask.any():
  1223. raise KeyError(f"{key[mask]} not in index")
  1224. self._set_values(indexer, value, warn=warn)
  1225. def _set_values(self, key, value, warn: bool = True) -> None:
  1226. if isinstance(key, (Index, Series)):
  1227. key = key._values
  1228. self._mgr = self._mgr.setitem(indexer=key, value=value, warn=warn)
  1229. self._maybe_update_cacher()
  1230. def _set_value(self, label, value, takeable: bool = False) -> None:
  1231. """
  1232. Quickly set single value at passed label.
  1233. If label is not contained, a new object is created with the label
  1234. placed at the end of the result index.
  1235. Parameters
  1236. ----------
  1237. label : object
  1238. Partial indexing with MultiIndex not allowed.
  1239. value : object
  1240. Scalar value.
  1241. takeable : interpret the index as indexers, default False
  1242. """
  1243. if not takeable:
  1244. try:
  1245. loc = self.index.get_loc(label)
  1246. except KeyError:
  1247. # set using a non-recursive method
  1248. self.loc[label] = value
  1249. return
  1250. else:
  1251. loc = label
  1252. self._set_values(loc, value)
  1253. # ----------------------------------------------------------------------
  1254. # Lookup Caching
  1255. @property
  1256. def _is_cached(self) -> bool:
  1257. """Return boolean indicating if self is cached or not."""
  1258. return getattr(self, "_cacher", None) is not None
  1259. def _get_cacher(self):
  1260. """return my cacher or None"""
  1261. cacher = getattr(self, "_cacher", None)
  1262. if cacher is not None:
  1263. cacher = cacher[1]()
  1264. return cacher
  1265. def _reset_cacher(self) -> None:
  1266. """
  1267. Reset the cacher.
  1268. """
  1269. if hasattr(self, "_cacher"):
  1270. del self._cacher
  1271. def _set_as_cached(self, item, cacher) -> None:
  1272. """
  1273. Set the _cacher attribute on the calling object with a weakref to
  1274. cacher.
  1275. """
  1276. if using_copy_on_write():
  1277. return
  1278. self._cacher = (item, weakref.ref(cacher))
  1279. def _clear_item_cache(self) -> None:
  1280. # no-op for Series
  1281. pass
  1282. def _check_is_chained_assignment_possible(self) -> bool:
  1283. """
  1284. See NDFrame._check_is_chained_assignment_possible.__doc__
  1285. """
  1286. if self._is_view and self._is_cached:
  1287. ref = self._get_cacher()
  1288. if ref is not None and ref._is_mixed_type:
  1289. self._check_setitem_copy(t="referent", force=True)
  1290. return True
  1291. return super()._check_is_chained_assignment_possible()
  1292. def _maybe_update_cacher(
  1293. self, clear: bool = False, verify_is_copy: bool = True, inplace: bool = False
  1294. ) -> None:
  1295. """
  1296. See NDFrame._maybe_update_cacher.__doc__
  1297. """
  1298. # for CoW, we never want to update the parent DataFrame cache
  1299. # if the Series changed, but don't keep track of any cacher
  1300. if using_copy_on_write():
  1301. return
  1302. cacher = getattr(self, "_cacher", None)
  1303. if cacher is not None:
  1304. ref: DataFrame = cacher[1]()
  1305. # we are trying to reference a dead referent, hence
  1306. # a copy
  1307. if ref is None:
  1308. del self._cacher
  1309. elif len(self) == len(ref) and self.name in ref.columns:
  1310. # GH#42530 self.name must be in ref.columns
  1311. # to ensure column still in dataframe
  1312. # otherwise, either self or ref has swapped in new arrays
  1313. ref._maybe_cache_changed(cacher[0], self, inplace=inplace)
  1314. else:
  1315. # GH#33675 we have swapped in a new array, so parent
  1316. # reference to self is now invalid
  1317. ref._item_cache.pop(cacher[0], None)
  1318. super()._maybe_update_cacher(
  1319. clear=clear, verify_is_copy=verify_is_copy, inplace=inplace
  1320. )
  1321. # ----------------------------------------------------------------------
  1322. # Unsorted
  1323. def repeat(self, repeats: int | Sequence[int], axis: None = None) -> Series:
  1324. """
  1325. Repeat elements of a Series.
  1326. Returns a new Series where each element of the current Series
  1327. is repeated consecutively a given number of times.
  1328. Parameters
  1329. ----------
  1330. repeats : int or array of ints
  1331. The number of repetitions for each element. This should be a
  1332. non-negative integer. Repeating 0 times will return an empty
  1333. Series.
  1334. axis : None
  1335. Unused. Parameter needed for compatibility with DataFrame.
  1336. Returns
  1337. -------
  1338. Series
  1339. Newly created Series with repeated elements.
  1340. See Also
  1341. --------
  1342. Index.repeat : Equivalent function for Index.
  1343. numpy.repeat : Similar method for :class:`numpy.ndarray`.
  1344. Examples
  1345. --------
  1346. >>> s = pd.Series(['a', 'b', 'c'])
  1347. >>> s
  1348. 0 a
  1349. 1 b
  1350. 2 c
  1351. dtype: object
  1352. >>> s.repeat(2)
  1353. 0 a
  1354. 0 a
  1355. 1 b
  1356. 1 b
  1357. 2 c
  1358. 2 c
  1359. dtype: object
  1360. >>> s.repeat([1, 2, 3])
  1361. 0 a
  1362. 1 b
  1363. 1 b
  1364. 2 c
  1365. 2 c
  1366. 2 c
  1367. dtype: object
  1368. """
  1369. nv.validate_repeat((), {"axis": axis})
  1370. new_index = self.index.repeat(repeats)
  1371. new_values = self._values.repeat(repeats)
  1372. return self._constructor(new_values, index=new_index, copy=False).__finalize__(
  1373. self, method="repeat"
  1374. )
  1375. @overload
  1376. def reset_index(
  1377. self,
  1378. level: IndexLabel = ...,
  1379. *,
  1380. drop: Literal[False] = ...,
  1381. name: Level = ...,
  1382. inplace: Literal[False] = ...,
  1383. allow_duplicates: bool = ...,
  1384. ) -> DataFrame:
  1385. ...
  1386. @overload
  1387. def reset_index(
  1388. self,
  1389. level: IndexLabel = ...,
  1390. *,
  1391. drop: Literal[True],
  1392. name: Level = ...,
  1393. inplace: Literal[False] = ...,
  1394. allow_duplicates: bool = ...,
  1395. ) -> Series:
  1396. ...
  1397. @overload
  1398. def reset_index(
  1399. self,
  1400. level: IndexLabel = ...,
  1401. *,
  1402. drop: bool = ...,
  1403. name: Level = ...,
  1404. inplace: Literal[True],
  1405. allow_duplicates: bool = ...,
  1406. ) -> None:
  1407. ...
  1408. def reset_index(
  1409. self,
  1410. level: IndexLabel | None = None,
  1411. *,
  1412. drop: bool = False,
  1413. name: Level = lib.no_default,
  1414. inplace: bool = False,
  1415. allow_duplicates: bool = False,
  1416. ) -> DataFrame | Series | None:
  1417. """
  1418. Generate a new DataFrame or Series with the index reset.
  1419. This is useful when the index needs to be treated as a column, or
  1420. when the index is meaningless and needs to be reset to the default
  1421. before another operation.
  1422. Parameters
  1423. ----------
  1424. level : int, str, tuple, or list, default optional
  1425. For a Series with a MultiIndex, only remove the specified levels
  1426. from the index. Removes all levels by default.
  1427. drop : bool, default False
  1428. Just reset the index, without inserting it as a column in
  1429. the new DataFrame.
  1430. name : object, optional
  1431. The name to use for the column containing the original Series
  1432. values. Uses ``self.name`` by default. This argument is ignored
  1433. when `drop` is True.
  1434. inplace : bool, default False
  1435. Modify the Series in place (do not create a new object).
  1436. allow_duplicates : bool, default False
  1437. Allow duplicate column labels to be created.
  1438. .. versionadded:: 1.5.0
  1439. Returns
  1440. -------
  1441. Series or DataFrame or None
  1442. When `drop` is False (the default), a DataFrame is returned.
  1443. The newly created columns will come first in the DataFrame,
  1444. followed by the original Series values.
  1445. When `drop` is True, a `Series` is returned.
  1446. In either case, if ``inplace=True``, no value is returned.
  1447. See Also
  1448. --------
  1449. DataFrame.reset_index: Analogous function for DataFrame.
  1450. Examples
  1451. --------
  1452. >>> s = pd.Series([1, 2, 3, 4], name='foo',
  1453. ... index=pd.Index(['a', 'b', 'c', 'd'], name='idx'))
  1454. Generate a DataFrame with default index.
  1455. >>> s.reset_index()
  1456. idx foo
  1457. 0 a 1
  1458. 1 b 2
  1459. 2 c 3
  1460. 3 d 4
  1461. To specify the name of the new column use `name`.
  1462. >>> s.reset_index(name='values')
  1463. idx values
  1464. 0 a 1
  1465. 1 b 2
  1466. 2 c 3
  1467. 3 d 4
  1468. To generate a new Series with the default set `drop` to True.
  1469. >>> s.reset_index(drop=True)
  1470. 0 1
  1471. 1 2
  1472. 2 3
  1473. 3 4
  1474. Name: foo, dtype: int64
  1475. The `level` parameter is interesting for Series with a multi-level
  1476. index.
  1477. >>> arrays = [np.array(['bar', 'bar', 'baz', 'baz']),
  1478. ... np.array(['one', 'two', 'one', 'two'])]
  1479. >>> s2 = pd.Series(
  1480. ... range(4), name='foo',
  1481. ... index=pd.MultiIndex.from_arrays(arrays,
  1482. ... names=['a', 'b']))
  1483. To remove a specific level from the Index, use `level`.
  1484. >>> s2.reset_index(level='a')
  1485. a foo
  1486. b
  1487. one bar 0
  1488. two bar 1
  1489. one baz 2
  1490. two baz 3
  1491. If `level` is not set, all levels are removed from the Index.
  1492. >>> s2.reset_index()
  1493. a b foo
  1494. 0 bar one 0
  1495. 1 bar two 1
  1496. 2 baz one 2
  1497. 3 baz two 3
  1498. """
  1499. inplace = validate_bool_kwarg(inplace, "inplace")
  1500. if drop:
  1501. new_index = default_index(len(self))
  1502. if level is not None:
  1503. level_list: Sequence[Hashable]
  1504. if not isinstance(level, (tuple, list)):
  1505. level_list = [level]
  1506. else:
  1507. level_list = level
  1508. level_list = [self.index._get_level_number(lev) for lev in level_list]
  1509. if len(level_list) < self.index.nlevels:
  1510. new_index = self.index.droplevel(level_list)
  1511. if inplace:
  1512. self.index = new_index
  1513. elif using_copy_on_write():
  1514. new_ser = self.copy(deep=False)
  1515. new_ser.index = new_index
  1516. return new_ser.__finalize__(self, method="reset_index")
  1517. else:
  1518. return self._constructor(
  1519. self._values.copy(), index=new_index, copy=False, dtype=self.dtype
  1520. ).__finalize__(self, method="reset_index")
  1521. elif inplace:
  1522. raise TypeError(
  1523. "Cannot reset_index inplace on a Series to create a DataFrame"
  1524. )
  1525. else:
  1526. if name is lib.no_default:
  1527. # For backwards compatibility, keep columns as [0] instead of
  1528. # [None] when self.name is None
  1529. if self.name is None:
  1530. name = 0
  1531. else:
  1532. name = self.name
  1533. df = self.to_frame(name)
  1534. return df.reset_index(
  1535. level=level, drop=drop, allow_duplicates=allow_duplicates
  1536. )
  1537. return None
  1538. # ----------------------------------------------------------------------
  1539. # Rendering Methods
  1540. def __repr__(self) -> str:
  1541. """
  1542. Return a string representation for a particular Series.
  1543. """
  1544. # pylint: disable=invalid-repr-returned
  1545. repr_params = fmt.get_series_repr_params()
  1546. return self.to_string(**repr_params)
  1547. @overload
  1548. def to_string(
  1549. self,
  1550. buf: None = ...,
  1551. na_rep: str = ...,
  1552. float_format: str | None = ...,
  1553. header: bool = ...,
  1554. index: bool = ...,
  1555. length: bool = ...,
  1556. dtype=...,
  1557. name=...,
  1558. max_rows: int | None = ...,
  1559. min_rows: int | None = ...,
  1560. ) -> str:
  1561. ...
  1562. @overload
  1563. def to_string(
  1564. self,
  1565. buf: FilePath | WriteBuffer[str],
  1566. na_rep: str = ...,
  1567. float_format: str | None = ...,
  1568. header: bool = ...,
  1569. index: bool = ...,
  1570. length: bool = ...,
  1571. dtype=...,
  1572. name=...,
  1573. max_rows: int | None = ...,
  1574. min_rows: int | None = ...,
  1575. ) -> None:
  1576. ...
  1577. def to_string(
  1578. self,
  1579. buf: FilePath | WriteBuffer[str] | None = None,
  1580. na_rep: str = "NaN",
  1581. float_format: str | None = None,
  1582. header: bool = True,
  1583. index: bool = True,
  1584. length: bool = False,
  1585. dtype: bool = False,
  1586. name: bool = False,
  1587. max_rows: int | None = None,
  1588. min_rows: int | None = None,
  1589. ) -> str | None:
  1590. """
  1591. Render a string representation of the Series.
  1592. Parameters
  1593. ----------
  1594. buf : StringIO-like, optional
  1595. Buffer to write to.
  1596. na_rep : str, optional
  1597. String representation of NaN to use, default 'NaN'.
  1598. float_format : one-parameter function, optional
  1599. Formatter function to apply to columns' elements if they are
  1600. floats, default None.
  1601. header : bool, default True
  1602. Add the Series header (index name).
  1603. index : bool, optional
  1604. Add index (row) labels, default True.
  1605. length : bool, default False
  1606. Add the Series length.
  1607. dtype : bool, default False
  1608. Add the Series dtype.
  1609. name : bool, default False
  1610. Add the Series name if not None.
  1611. max_rows : int, optional
  1612. Maximum number of rows to show before truncating. If None, show
  1613. all.
  1614. min_rows : int, optional
  1615. The number of rows to display in a truncated repr (when number
  1616. of rows is above `max_rows`).
  1617. Returns
  1618. -------
  1619. str or None
  1620. String representation of Series if ``buf=None``, otherwise None.
  1621. Examples
  1622. --------
  1623. >>> ser = pd.Series([1, 2, 3]).to_string()
  1624. >>> ser
  1625. '0 1\\n1 2\\n2 3'
  1626. """
  1627. formatter = fmt.SeriesFormatter(
  1628. self,
  1629. name=name,
  1630. length=length,
  1631. header=header,
  1632. index=index,
  1633. dtype=dtype,
  1634. na_rep=na_rep,
  1635. float_format=float_format,
  1636. min_rows=min_rows,
  1637. max_rows=max_rows,
  1638. )
  1639. result = formatter.to_string()
  1640. # catch contract violations
  1641. if not isinstance(result, str):
  1642. raise AssertionError(
  1643. "result must be of type str, type "
  1644. f"of result is {repr(type(result).__name__)}"
  1645. )
  1646. if buf is None:
  1647. return result
  1648. else:
  1649. if hasattr(buf, "write"):
  1650. buf.write(result)
  1651. else:
  1652. with open(buf, "w", encoding="utf-8") as f:
  1653. f.write(result)
  1654. return None
  1655. @doc(
  1656. klass=_shared_doc_kwargs["klass"],
  1657. storage_options=_shared_docs["storage_options"],
  1658. examples=dedent(
  1659. """Examples
  1660. --------
  1661. >>> s = pd.Series(["elk", "pig", "dog", "quetzal"], name="animal")
  1662. >>> print(s.to_markdown())
  1663. | | animal |
  1664. |---:|:---------|
  1665. | 0 | elk |
  1666. | 1 | pig |
  1667. | 2 | dog |
  1668. | 3 | quetzal |
  1669. Output markdown with a tabulate option.
  1670. >>> print(s.to_markdown(tablefmt="grid"))
  1671. +----+----------+
  1672. | | animal |
  1673. +====+==========+
  1674. | 0 | elk |
  1675. +----+----------+
  1676. | 1 | pig |
  1677. +----+----------+
  1678. | 2 | dog |
  1679. +----+----------+
  1680. | 3 | quetzal |
  1681. +----+----------+"""
  1682. ),
  1683. )
  1684. def to_markdown(
  1685. self,
  1686. buf: IO[str] | None = None,
  1687. mode: str = "wt",
  1688. index: bool = True,
  1689. storage_options: StorageOptions | None = None,
  1690. **kwargs,
  1691. ) -> str | None:
  1692. """
  1693. Print {klass} in Markdown-friendly format.
  1694. Parameters
  1695. ----------
  1696. buf : str, Path or StringIO-like, optional, default None
  1697. Buffer to write to. If None, the output is returned as a string.
  1698. mode : str, optional
  1699. Mode in which file is opened, "wt" by default.
  1700. index : bool, optional, default True
  1701. Add index (row) labels.
  1702. {storage_options}
  1703. **kwargs
  1704. These parameters will be passed to `tabulate \
  1705. <https://pypi.org/project/tabulate>`_.
  1706. Returns
  1707. -------
  1708. str
  1709. {klass} in Markdown-friendly format.
  1710. Notes
  1711. -----
  1712. Requires the `tabulate <https://pypi.org/project/tabulate>`_ package.
  1713. {examples}
  1714. """
  1715. return self.to_frame().to_markdown(
  1716. buf, mode=mode, index=index, storage_options=storage_options, **kwargs
  1717. )
  1718. # ----------------------------------------------------------------------
  1719. def items(self) -> Iterable[tuple[Hashable, Any]]:
  1720. """
  1721. Lazily iterate over (index, value) tuples.
  1722. This method returns an iterable tuple (index, value). This is
  1723. convenient if you want to create a lazy iterator.
  1724. Returns
  1725. -------
  1726. iterable
  1727. Iterable of tuples containing the (index, value) pairs from a
  1728. Series.
  1729. See Also
  1730. --------
  1731. DataFrame.items : Iterate over (column name, Series) pairs.
  1732. DataFrame.iterrows : Iterate over DataFrame rows as (index, Series) pairs.
  1733. Examples
  1734. --------
  1735. >>> s = pd.Series(['A', 'B', 'C'])
  1736. >>> for index, value in s.items():
  1737. ... print(f"Index : {index}, Value : {value}")
  1738. Index : 0, Value : A
  1739. Index : 1, Value : B
  1740. Index : 2, Value : C
  1741. """
  1742. return zip(iter(self.index), iter(self))
  1743. # ----------------------------------------------------------------------
  1744. # Misc public methods
  1745. def keys(self) -> Index:
  1746. """
  1747. Return alias for index.
  1748. Returns
  1749. -------
  1750. Index
  1751. Index of the Series.
  1752. Examples
  1753. --------
  1754. >>> s = pd.Series([1, 2, 3], index=[0, 1, 2])
  1755. >>> s.keys()
  1756. Index([0, 1, 2], dtype='int64')
  1757. """
  1758. return self.index
  1759. @overload
  1760. def to_dict(
  1761. self, *, into: type[MutableMappingT] | MutableMappingT
  1762. ) -> MutableMappingT:
  1763. ...
  1764. @overload
  1765. def to_dict(self, *, into: type[dict] = ...) -> dict:
  1766. ...
  1767. # error: Incompatible default for argument "into" (default has type "type[
  1768. # dict[Any, Any]]", argument has type "type[MutableMappingT] | MutableMappingT")
  1769. @deprecate_nonkeyword_arguments(
  1770. version="3.0", allowed_args=["self"], name="to_dict"
  1771. )
  1772. def to_dict(
  1773. self,
  1774. into: type[MutableMappingT]
  1775. | MutableMappingT = dict, # type: ignore[assignment]
  1776. ) -> MutableMappingT:
  1777. """
  1778. Convert Series to {label -> value} dict or dict-like object.
  1779. Parameters
  1780. ----------
  1781. into : class, default dict
  1782. The collections.abc.MutableMapping subclass to use as the return
  1783. object. Can be the actual class or an empty instance of the mapping
  1784. type you want. If you want a collections.defaultdict, you must
  1785. pass it initialized.
  1786. Returns
  1787. -------
  1788. collections.abc.MutableMapping
  1789. Key-value representation of Series.
  1790. Examples
  1791. --------
  1792. >>> s = pd.Series([1, 2, 3, 4])
  1793. >>> s.to_dict()
  1794. {0: 1, 1: 2, 2: 3, 3: 4}
  1795. >>> from collections import OrderedDict, defaultdict
  1796. >>> s.to_dict(into=OrderedDict)
  1797. OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)])
  1798. >>> dd = defaultdict(list)
  1799. >>> s.to_dict(into=dd)
  1800. defaultdict(<class 'list'>, {0: 1, 1: 2, 2: 3, 3: 4})
  1801. """
  1802. # GH16122
  1803. into_c = com.standardize_mapping(into)
  1804. if is_object_dtype(self.dtype) or isinstance(self.dtype, ExtensionDtype):
  1805. return into_c((k, maybe_box_native(v)) for k, v in self.items())
  1806. else:
  1807. # Not an object dtype => all types will be the same so let the default
  1808. # indexer return native python type
  1809. return into_c(self.items())
  1810. def to_frame(self, name: Hashable = lib.no_default) -> DataFrame:
  1811. """
  1812. Convert Series to DataFrame.
  1813. Parameters
  1814. ----------
  1815. name : object, optional
  1816. The passed name should substitute for the series name (if it has
  1817. one).
  1818. Returns
  1819. -------
  1820. DataFrame
  1821. DataFrame representation of Series.
  1822. Examples
  1823. --------
  1824. >>> s = pd.Series(["a", "b", "c"],
  1825. ... name="vals")
  1826. >>> s.to_frame()
  1827. vals
  1828. 0 a
  1829. 1 b
  1830. 2 c
  1831. """
  1832. columns: Index
  1833. if name is lib.no_default:
  1834. name = self.name
  1835. if name is None:
  1836. # default to [0], same as we would get with DataFrame(self)
  1837. columns = default_index(1)
  1838. else:
  1839. columns = Index([name])
  1840. else:
  1841. columns = Index([name])
  1842. mgr = self._mgr.to_2d_mgr(columns)
  1843. df = self._constructor_expanddim_from_mgr(mgr, axes=mgr.axes)
  1844. return df.__finalize__(self, method="to_frame")
  1845. def _set_name(
  1846. self, name, inplace: bool = False, deep: bool | None = None
  1847. ) -> Series:
  1848. """
  1849. Set the Series name.
  1850. Parameters
  1851. ----------
  1852. name : str
  1853. inplace : bool
  1854. Whether to modify `self` directly or return a copy.
  1855. deep : bool|None, default None
  1856. Whether to do a deep copy, a shallow copy, or Copy on Write(None)
  1857. """
  1858. inplace = validate_bool_kwarg(inplace, "inplace")
  1859. ser = self if inplace else self.copy(deep and not using_copy_on_write())
  1860. ser.name = name
  1861. return ser
  1862. @Appender(
  1863. dedent(
  1864. """
  1865. Examples
  1866. --------
  1867. >>> ser = pd.Series([390., 350., 30., 20.],
  1868. ... index=['Falcon', 'Falcon', 'Parrot', 'Parrot'],
  1869. ... name="Max Speed")
  1870. >>> ser
  1871. Falcon 390.0
  1872. Falcon 350.0
  1873. Parrot 30.0
  1874. Parrot 20.0
  1875. Name: Max Speed, dtype: float64
  1876. >>> ser.groupby(["a", "b", "a", "b"]).mean()
  1877. a 210.0
  1878. b 185.0
  1879. Name: Max Speed, dtype: float64
  1880. >>> ser.groupby(level=0).mean()
  1881. Falcon 370.0
  1882. Parrot 25.0
  1883. Name: Max Speed, dtype: float64
  1884. >>> ser.groupby(ser > 100).mean()
  1885. Max Speed
  1886. False 25.0
  1887. True 370.0
  1888. Name: Max Speed, dtype: float64
  1889. **Grouping by Indexes**
  1890. We can groupby different levels of a hierarchical index
  1891. using the `level` parameter:
  1892. >>> arrays = [['Falcon', 'Falcon', 'Parrot', 'Parrot'],
  1893. ... ['Captive', 'Wild', 'Captive', 'Wild']]
  1894. >>> index = pd.MultiIndex.from_arrays(arrays, names=('Animal', 'Type'))
  1895. >>> ser = pd.Series([390., 350., 30., 20.], index=index, name="Max Speed")
  1896. >>> ser
  1897. Animal Type
  1898. Falcon Captive 390.0
  1899. Wild 350.0
  1900. Parrot Captive 30.0
  1901. Wild 20.0
  1902. Name: Max Speed, dtype: float64
  1903. >>> ser.groupby(level=0).mean()
  1904. Animal
  1905. Falcon 370.0
  1906. Parrot 25.0
  1907. Name: Max Speed, dtype: float64
  1908. >>> ser.groupby(level="Type").mean()
  1909. Type
  1910. Captive 210.0
  1911. Wild 185.0
  1912. Name: Max Speed, dtype: float64
  1913. We can also choose to include `NA` in group keys or not by defining
  1914. `dropna` parameter, the default setting is `True`.
  1915. >>> ser = pd.Series([1, 2, 3, 3], index=["a", 'a', 'b', np.nan])
  1916. >>> ser.groupby(level=0).sum()
  1917. a 3
  1918. b 3
  1919. dtype: int64
  1920. >>> ser.groupby(level=0, dropna=False).sum()
  1921. a 3
  1922. b 3
  1923. NaN 3
  1924. dtype: int64
  1925. >>> arrays = ['Falcon', 'Falcon', 'Parrot', 'Parrot']
  1926. >>> ser = pd.Series([390., 350., 30., 20.], index=arrays, name="Max Speed")
  1927. >>> ser.groupby(["a", "b", "a", np.nan]).mean()
  1928. a 210.0
  1929. b 350.0
  1930. Name: Max Speed, dtype: float64
  1931. >>> ser.groupby(["a", "b", "a", np.nan], dropna=False).mean()
  1932. a 210.0
  1933. b 350.0
  1934. NaN 20.0
  1935. Name: Max Speed, dtype: float64
  1936. """
  1937. )
  1938. )
  1939. @Appender(_shared_docs["groupby"] % _shared_doc_kwargs)
  1940. def groupby(
  1941. self,
  1942. by=None,
  1943. axis: Axis = 0,
  1944. level: IndexLabel | None = None,
  1945. as_index: bool = True,
  1946. sort: bool = True,
  1947. group_keys: bool = True,
  1948. observed: bool | lib.NoDefault = lib.no_default,
  1949. dropna: bool = True,
  1950. ) -> SeriesGroupBy:
  1951. from pandas.core.groupby.generic import SeriesGroupBy
  1952. if level is None and by is None:
  1953. raise TypeError("You have to supply one of 'by' and 'level'")
  1954. if not as_index:
  1955. raise TypeError("as_index=False only valid with DataFrame")
  1956. axis = self._get_axis_number(axis)
  1957. return SeriesGroupBy(
  1958. obj=self,
  1959. keys=by,
  1960. axis=axis,
  1961. level=level,
  1962. as_index=as_index,
  1963. sort=sort,
  1964. group_keys=group_keys,
  1965. observed=observed,
  1966. dropna=dropna,
  1967. )
  1968. # ----------------------------------------------------------------------
  1969. # Statistics, overridden ndarray methods
  1970. # TODO: integrate bottleneck
  1971. def count(self) -> int:
  1972. """
  1973. Return number of non-NA/null observations in the Series.
  1974. Returns
  1975. -------
  1976. int
  1977. Number of non-null values in the Series.
  1978. See Also
  1979. --------
  1980. DataFrame.count : Count non-NA cells for each column or row.
  1981. Examples
  1982. --------
  1983. >>> s = pd.Series([0.0, 1.0, np.nan])
  1984. >>> s.count()
  1985. 2
  1986. """
  1987. return notna(self._values).sum().astype("int64")
  1988. def mode(self, dropna: bool = True) -> Series:
  1989. """
  1990. Return the mode(s) of the Series.
  1991. The mode is the value that appears most often. There can be multiple modes.
  1992. Always returns Series even if only one value is returned.
  1993. Parameters
  1994. ----------
  1995. dropna : bool, default True
  1996. Don't consider counts of NaN/NaT.
  1997. Returns
  1998. -------
  1999. Series
  2000. Modes of the Series in sorted order.
  2001. Examples
  2002. --------
  2003. >>> s = pd.Series([2, 4, 2, 2, 4, None])
  2004. >>> s.mode()
  2005. 0 2.0
  2006. dtype: float64
  2007. More than one mode:
  2008. >>> s = pd.Series([2, 4, 8, 2, 4, None])
  2009. >>> s.mode()
  2010. 0 2.0
  2011. 1 4.0
  2012. dtype: float64
  2013. With and without considering null value:
  2014. >>> s = pd.Series([2, 4, None, None, 4, None])
  2015. >>> s.mode(dropna=False)
  2016. 0 NaN
  2017. dtype: float64
  2018. >>> s = pd.Series([2, 4, None, None, 4, None])
  2019. >>> s.mode()
  2020. 0 4.0
  2021. dtype: float64
  2022. """
  2023. # TODO: Add option for bins like value_counts()
  2024. values = self._values
  2025. if isinstance(values, np.ndarray):
  2026. res_values = algorithms.mode(values, dropna=dropna)
  2027. else:
  2028. res_values = values._mode(dropna=dropna)
  2029. # Ensure index is type stable (should always use int index)
  2030. return self._constructor(
  2031. res_values,
  2032. index=range(len(res_values)),
  2033. name=self.name,
  2034. copy=False,
  2035. dtype=self.dtype,
  2036. ).__finalize__(self, method="mode")
  2037. def unique(self) -> ArrayLike: # pylint: disable=useless-parent-delegation
  2038. """
  2039. Return unique values of Series object.
  2040. Uniques are returned in order of appearance. Hash table-based unique,
  2041. therefore does NOT sort.
  2042. Returns
  2043. -------
  2044. ndarray or ExtensionArray
  2045. The unique values returned as a NumPy array. See Notes.
  2046. See Also
  2047. --------
  2048. Series.drop_duplicates : Return Series with duplicate values removed.
  2049. unique : Top-level unique method for any 1-d array-like object.
  2050. Index.unique : Return Index with unique values from an Index object.
  2051. Notes
  2052. -----
  2053. Returns the unique values as a NumPy array. In case of an
  2054. extension-array backed Series, a new
  2055. :class:`~api.extensions.ExtensionArray` of that type with just
  2056. the unique values is returned. This includes
  2057. * Categorical
  2058. * Period
  2059. * Datetime with Timezone
  2060. * Datetime without Timezone
  2061. * Timedelta
  2062. * Interval
  2063. * Sparse
  2064. * IntegerNA
  2065. See Examples section.
  2066. Examples
  2067. --------
  2068. >>> pd.Series([2, 1, 3, 3], name='A').unique()
  2069. array([2, 1, 3])
  2070. >>> pd.Series([pd.Timestamp('2016-01-01') for _ in range(3)]).unique()
  2071. <DatetimeArray>
  2072. ['2016-01-01 00:00:00']
  2073. Length: 1, dtype: datetime64[ns]
  2074. >>> pd.Series([pd.Timestamp('2016-01-01', tz='US/Eastern')
  2075. ... for _ in range(3)]).unique()
  2076. <DatetimeArray>
  2077. ['2016-01-01 00:00:00-05:00']
  2078. Length: 1, dtype: datetime64[ns, US/Eastern]
  2079. An Categorical will return categories in the order of
  2080. appearance and with the same dtype.
  2081. >>> pd.Series(pd.Categorical(list('baabc'))).unique()
  2082. ['b', 'a', 'c']
  2083. Categories (3, object): ['a', 'b', 'c']
  2084. >>> pd.Series(pd.Categorical(list('baabc'), categories=list('abc'),
  2085. ... ordered=True)).unique()
  2086. ['b', 'a', 'c']
  2087. Categories (3, object): ['a' < 'b' < 'c']
  2088. """
  2089. return super().unique()
  2090. @overload
  2091. def drop_duplicates(
  2092. self,
  2093. *,
  2094. keep: DropKeep = ...,
  2095. inplace: Literal[False] = ...,
  2096. ignore_index: bool = ...,
  2097. ) -> Series:
  2098. ...
  2099. @overload
  2100. def drop_duplicates(
  2101. self, *, keep: DropKeep = ..., inplace: Literal[True], ignore_index: bool = ...
  2102. ) -> None:
  2103. ...
  2104. @overload
  2105. def drop_duplicates(
  2106. self, *, keep: DropKeep = ..., inplace: bool = ..., ignore_index: bool = ...
  2107. ) -> Series | None:
  2108. ...
  2109. def drop_duplicates(
  2110. self,
  2111. *,
  2112. keep: DropKeep = "first",
  2113. inplace: bool = False,
  2114. ignore_index: bool = False,
  2115. ) -> Series | None:
  2116. """
  2117. Return Series with duplicate values removed.
  2118. Parameters
  2119. ----------
  2120. keep : {'first', 'last', ``False``}, default 'first'
  2121. Method to handle dropping duplicates:
  2122. - 'first' : Drop duplicates except for the first occurrence.
  2123. - 'last' : Drop duplicates except for the last occurrence.
  2124. - ``False`` : Drop all duplicates.
  2125. inplace : bool, default ``False``
  2126. If ``True``, performs operation inplace and returns None.
  2127. ignore_index : bool, default ``False``
  2128. If ``True``, the resulting axis will be labeled 0, 1, …, n - 1.
  2129. .. versionadded:: 2.0.0
  2130. Returns
  2131. -------
  2132. Series or None
  2133. Series with duplicates dropped or None if ``inplace=True``.
  2134. See Also
  2135. --------
  2136. Index.drop_duplicates : Equivalent method on Index.
  2137. DataFrame.drop_duplicates : Equivalent method on DataFrame.
  2138. Series.duplicated : Related method on Series, indicating duplicate
  2139. Series values.
  2140. Series.unique : Return unique values as an array.
  2141. Examples
  2142. --------
  2143. Generate a Series with duplicated entries.
  2144. >>> s = pd.Series(['llama', 'cow', 'llama', 'beetle', 'llama', 'hippo'],
  2145. ... name='animal')
  2146. >>> s
  2147. 0 llama
  2148. 1 cow
  2149. 2 llama
  2150. 3 beetle
  2151. 4 llama
  2152. 5 hippo
  2153. Name: animal, dtype: object
  2154. With the 'keep' parameter, the selection behaviour of duplicated values
  2155. can be changed. The value 'first' keeps the first occurrence for each
  2156. set of duplicated entries. The default value of keep is 'first'.
  2157. >>> s.drop_duplicates()
  2158. 0 llama
  2159. 1 cow
  2160. 3 beetle
  2161. 5 hippo
  2162. Name: animal, dtype: object
  2163. The value 'last' for parameter 'keep' keeps the last occurrence for
  2164. each set of duplicated entries.
  2165. >>> s.drop_duplicates(keep='last')
  2166. 1 cow
  2167. 3 beetle
  2168. 4 llama
  2169. 5 hippo
  2170. Name: animal, dtype: object
  2171. The value ``False`` for parameter 'keep' discards all sets of
  2172. duplicated entries.
  2173. >>> s.drop_duplicates(keep=False)
  2174. 1 cow
  2175. 3 beetle
  2176. 5 hippo
  2177. Name: animal, dtype: object
  2178. """
  2179. inplace = validate_bool_kwarg(inplace, "inplace")
  2180. result = super().drop_duplicates(keep=keep)
  2181. if ignore_index:
  2182. result.index = default_index(len(result))
  2183. if inplace:
  2184. self._update_inplace(result)
  2185. return None
  2186. else:
  2187. return result
  2188. def duplicated(self, keep: DropKeep = "first") -> Series:
  2189. """
  2190. Indicate duplicate Series values.
  2191. Duplicated values are indicated as ``True`` values in the resulting
  2192. Series. Either all duplicates, all except the first or all except the
  2193. last occurrence of duplicates can be indicated.
  2194. Parameters
  2195. ----------
  2196. keep : {'first', 'last', False}, default 'first'
  2197. Method to handle dropping duplicates:
  2198. - 'first' : Mark duplicates as ``True`` except for the first
  2199. occurrence.
  2200. - 'last' : Mark duplicates as ``True`` except for the last
  2201. occurrence.
  2202. - ``False`` : Mark all duplicates as ``True``.
  2203. Returns
  2204. -------
  2205. Series[bool]
  2206. Series indicating whether each value has occurred in the
  2207. preceding values.
  2208. See Also
  2209. --------
  2210. Index.duplicated : Equivalent method on pandas.Index.
  2211. DataFrame.duplicated : Equivalent method on pandas.DataFrame.
  2212. Series.drop_duplicates : Remove duplicate values from Series.
  2213. Examples
  2214. --------
  2215. By default, for each set of duplicated values, the first occurrence is
  2216. set on False and all others on True:
  2217. >>> animals = pd.Series(['llama', 'cow', 'llama', 'beetle', 'llama'])
  2218. >>> animals.duplicated()
  2219. 0 False
  2220. 1 False
  2221. 2 True
  2222. 3 False
  2223. 4 True
  2224. dtype: bool
  2225. which is equivalent to
  2226. >>> animals.duplicated(keep='first')
  2227. 0 False
  2228. 1 False
  2229. 2 True
  2230. 3 False
  2231. 4 True
  2232. dtype: bool
  2233. By using 'last', the last occurrence of each set of duplicated values
  2234. is set on False and all others on True:
  2235. >>> animals.duplicated(keep='last')
  2236. 0 True
  2237. 1 False
  2238. 2 True
  2239. 3 False
  2240. 4 False
  2241. dtype: bool
  2242. By setting keep on ``False``, all duplicates are True:
  2243. >>> animals.duplicated(keep=False)
  2244. 0 True
  2245. 1 False
  2246. 2 True
  2247. 3 False
  2248. 4 True
  2249. dtype: bool
  2250. """
  2251. res = self._duplicated(keep=keep)
  2252. result = self._constructor(res, index=self.index, copy=False)
  2253. return result.__finalize__(self, method="duplicated")
  2254. def idxmin(self, axis: Axis = 0, skipna: bool = True, *args, **kwargs) -> Hashable:
  2255. """
  2256. Return the row label of the minimum value.
  2257. If multiple values equal the minimum, the first row label with that
  2258. value is returned.
  2259. Parameters
  2260. ----------
  2261. axis : {0 or 'index'}
  2262. Unused. Parameter needed for compatibility with DataFrame.
  2263. skipna : bool, default True
  2264. Exclude NA/null values. If the entire Series is NA, the result
  2265. will be NA.
  2266. *args, **kwargs
  2267. Additional arguments and keywords have no effect but might be
  2268. accepted for compatibility with NumPy.
  2269. Returns
  2270. -------
  2271. Index
  2272. Label of the minimum value.
  2273. Raises
  2274. ------
  2275. ValueError
  2276. If the Series is empty.
  2277. See Also
  2278. --------
  2279. numpy.argmin : Return indices of the minimum values
  2280. along the given axis.
  2281. DataFrame.idxmin : Return index of first occurrence of minimum
  2282. over requested axis.
  2283. Series.idxmax : Return index *label* of the first occurrence
  2284. of maximum of values.
  2285. Notes
  2286. -----
  2287. This method is the Series version of ``ndarray.argmin``. This method
  2288. returns the label of the minimum, while ``ndarray.argmin`` returns
  2289. the position. To get the position, use ``series.values.argmin()``.
  2290. Examples
  2291. --------
  2292. >>> s = pd.Series(data=[1, None, 4, 1],
  2293. ... index=['A', 'B', 'C', 'D'])
  2294. >>> s
  2295. A 1.0
  2296. B NaN
  2297. C 4.0
  2298. D 1.0
  2299. dtype: float64
  2300. >>> s.idxmin()
  2301. 'A'
  2302. If `skipna` is False and there is an NA value in the data,
  2303. the function returns ``nan``.
  2304. >>> s.idxmin(skipna=False)
  2305. nan
  2306. """
  2307. axis = self._get_axis_number(axis)
  2308. with warnings.catch_warnings():
  2309. # TODO(3.0): this catching/filtering can be removed
  2310. # ignore warning produced by argmin since we will issue a different
  2311. # warning for idxmin
  2312. warnings.simplefilter("ignore")
  2313. i = self.argmin(axis, skipna, *args, **kwargs)
  2314. if i == -1:
  2315. # GH#43587 give correct NA value for Index.
  2316. warnings.warn(
  2317. f"The behavior of {type(self).__name__}.idxmin with all-NA "
  2318. "values, or any-NA and skipna=False, is deprecated. In a future "
  2319. "version this will raise ValueError",
  2320. FutureWarning,
  2321. stacklevel=find_stack_level(),
  2322. )
  2323. return self.index._na_value
  2324. return self.index[i]
  2325. def idxmax(self, axis: Axis = 0, skipna: bool = True, *args, **kwargs) -> Hashable:
  2326. """
  2327. Return the row label of the maximum value.
  2328. If multiple values equal the maximum, the first row label with that
  2329. value is returned.
  2330. Parameters
  2331. ----------
  2332. axis : {0 or 'index'}
  2333. Unused. Parameter needed for compatibility with DataFrame.
  2334. skipna : bool, default True
  2335. Exclude NA/null values. If the entire Series is NA, the result
  2336. will be NA.
  2337. *args, **kwargs
  2338. Additional arguments and keywords have no effect but might be
  2339. accepted for compatibility with NumPy.
  2340. Returns
  2341. -------
  2342. Index
  2343. Label of the maximum value.
  2344. Raises
  2345. ------
  2346. ValueError
  2347. If the Series is empty.
  2348. See Also
  2349. --------
  2350. numpy.argmax : Return indices of the maximum values
  2351. along the given axis.
  2352. DataFrame.idxmax : Return index of first occurrence of maximum
  2353. over requested axis.
  2354. Series.idxmin : Return index *label* of the first occurrence
  2355. of minimum of values.
  2356. Notes
  2357. -----
  2358. This method is the Series version of ``ndarray.argmax``. This method
  2359. returns the label of the maximum, while ``ndarray.argmax`` returns
  2360. the position. To get the position, use ``series.values.argmax()``.
  2361. Examples
  2362. --------
  2363. >>> s = pd.Series(data=[1, None, 4, 3, 4],
  2364. ... index=['A', 'B', 'C', 'D', 'E'])
  2365. >>> s
  2366. A 1.0
  2367. B NaN
  2368. C 4.0
  2369. D 3.0
  2370. E 4.0
  2371. dtype: float64
  2372. >>> s.idxmax()
  2373. 'C'
  2374. If `skipna` is False and there is an NA value in the data,
  2375. the function returns ``nan``.
  2376. >>> s.idxmax(skipna=False)
  2377. nan
  2378. """
  2379. axis = self._get_axis_number(axis)
  2380. with warnings.catch_warnings():
  2381. # TODO(3.0): this catching/filtering can be removed
  2382. # ignore warning produced by argmax since we will issue a different
  2383. # warning for argmax
  2384. warnings.simplefilter("ignore")
  2385. i = self.argmax(axis, skipna, *args, **kwargs)
  2386. if i == -1:
  2387. # GH#43587 give correct NA value for Index.
  2388. warnings.warn(
  2389. f"The behavior of {type(self).__name__}.idxmax with all-NA "
  2390. "values, or any-NA and skipna=False, is deprecated. In a future "
  2391. "version this will raise ValueError",
  2392. FutureWarning,
  2393. stacklevel=find_stack_level(),
  2394. )
  2395. return self.index._na_value
  2396. return self.index[i]
  2397. def round(self, decimals: int = 0, *args, **kwargs) -> Series:
  2398. """
  2399. Round each value in a Series to the given number of decimals.
  2400. Parameters
  2401. ----------
  2402. decimals : int, default 0
  2403. Number of decimal places to round to. If decimals is negative,
  2404. it specifies the number of positions to the left of the decimal point.
  2405. *args, **kwargs
  2406. Additional arguments and keywords have no effect but might be
  2407. accepted for compatibility with NumPy.
  2408. Returns
  2409. -------
  2410. Series
  2411. Rounded values of the Series.
  2412. See Also
  2413. --------
  2414. numpy.around : Round values of an np.array.
  2415. DataFrame.round : Round values of a DataFrame.
  2416. Examples
  2417. --------
  2418. >>> s = pd.Series([0.1, 1.3, 2.7])
  2419. >>> s.round()
  2420. 0 0.0
  2421. 1 1.0
  2422. 2 3.0
  2423. dtype: float64
  2424. """
  2425. nv.validate_round(args, kwargs)
  2426. if self.dtype == "object":
  2427. raise TypeError("Expected numeric dtype, got object instead.")
  2428. new_mgr = self._mgr.round(decimals=decimals, using_cow=using_copy_on_write())
  2429. return self._constructor_from_mgr(new_mgr, axes=new_mgr.axes).__finalize__(
  2430. self, method="round"
  2431. )
  2432. @overload
  2433. def quantile(
  2434. self, q: float = ..., interpolation: QuantileInterpolation = ...
  2435. ) -> float:
  2436. ...
  2437. @overload
  2438. def quantile(
  2439. self,
  2440. q: Sequence[float] | AnyArrayLike,
  2441. interpolation: QuantileInterpolation = ...,
  2442. ) -> Series:
  2443. ...
  2444. @overload
  2445. def quantile(
  2446. self,
  2447. q: float | Sequence[float] | AnyArrayLike = ...,
  2448. interpolation: QuantileInterpolation = ...,
  2449. ) -> float | Series:
  2450. ...
  2451. def quantile(
  2452. self,
  2453. q: float | Sequence[float] | AnyArrayLike = 0.5,
  2454. interpolation: QuantileInterpolation = "linear",
  2455. ) -> float | Series:
  2456. """
  2457. Return value at the given quantile.
  2458. Parameters
  2459. ----------
  2460. q : float or array-like, default 0.5 (50% quantile)
  2461. The quantile(s) to compute, which can lie in range: 0 <= q <= 1.
  2462. interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
  2463. This optional parameter specifies the interpolation method to use,
  2464. when the desired quantile lies between two data points `i` and `j`:
  2465. * linear: `i + (j - i) * (x-i)/(j-i)`, where `(x-i)/(j-i)` is
  2466. the fractional part of the index surrounded by `i > j`.
  2467. * lower: `i`.
  2468. * higher: `j`.
  2469. * nearest: `i` or `j` whichever is nearest.
  2470. * midpoint: (`i` + `j`) / 2.
  2471. Returns
  2472. -------
  2473. float or Series
  2474. If ``q`` is an array, a Series will be returned where the
  2475. index is ``q`` and the values are the quantiles, otherwise
  2476. a float will be returned.
  2477. See Also
  2478. --------
  2479. core.window.Rolling.quantile : Calculate the rolling quantile.
  2480. numpy.percentile : Returns the q-th percentile(s) of the array elements.
  2481. Examples
  2482. --------
  2483. >>> s = pd.Series([1, 2, 3, 4])
  2484. >>> s.quantile(.5)
  2485. 2.5
  2486. >>> s.quantile([.25, .5, .75])
  2487. 0.25 1.75
  2488. 0.50 2.50
  2489. 0.75 3.25
  2490. dtype: float64
  2491. """
  2492. validate_percentile(q)
  2493. # We dispatch to DataFrame so that core.internals only has to worry
  2494. # about 2D cases.
  2495. df = self.to_frame()
  2496. result = df.quantile(q=q, interpolation=interpolation, numeric_only=False)
  2497. if result.ndim == 2:
  2498. result = result.iloc[:, 0]
  2499. if is_list_like(q):
  2500. result.name = self.name
  2501. idx = Index(q, dtype=np.float64)
  2502. return self._constructor(result, index=idx, name=self.name)
  2503. else:
  2504. # scalar
  2505. return result.iloc[0]
  2506. def corr(
  2507. self,
  2508. other: Series,
  2509. method: CorrelationMethod = "pearson",
  2510. min_periods: int | None = None,
  2511. ) -> float:
  2512. """
  2513. Compute correlation with `other` Series, excluding missing values.
  2514. The two `Series` objects are not required to be the same length and will be
  2515. aligned internally before the correlation function is applied.
  2516. Parameters
  2517. ----------
  2518. other : Series
  2519. Series with which to compute the correlation.
  2520. method : {'pearson', 'kendall', 'spearman'} or callable
  2521. Method used to compute correlation:
  2522. - pearson : Standard correlation coefficient
  2523. - kendall : Kendall Tau correlation coefficient
  2524. - spearman : Spearman rank correlation
  2525. - callable: Callable with input two 1d ndarrays and returning a float.
  2526. .. warning::
  2527. Note that the returned matrix from corr will have 1 along the
  2528. diagonals and will be symmetric regardless of the callable's
  2529. behavior.
  2530. min_periods : int, optional
  2531. Minimum number of observations needed to have a valid result.
  2532. Returns
  2533. -------
  2534. float
  2535. Correlation with other.
  2536. See Also
  2537. --------
  2538. DataFrame.corr : Compute pairwise correlation between columns.
  2539. DataFrame.corrwith : Compute pairwise correlation with another
  2540. DataFrame or Series.
  2541. Notes
  2542. -----
  2543. Pearson, Kendall and Spearman correlation are currently computed using pairwise complete observations.
  2544. * `Pearson correlation coefficient <https://en.wikipedia.org/wiki/Pearson_correlation_coefficient>`_
  2545. * `Kendall rank correlation coefficient <https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient>`_
  2546. * `Spearman's rank correlation coefficient <https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient>`_
  2547. Automatic data alignment: as with all pandas operations, automatic data alignment is performed for this method.
  2548. ``corr()`` automatically considers values with matching indices.
  2549. Examples
  2550. --------
  2551. >>> def histogram_intersection(a, b):
  2552. ... v = np.minimum(a, b).sum().round(decimals=1)
  2553. ... return v
  2554. >>> s1 = pd.Series([.2, .0, .6, .2])
  2555. >>> s2 = pd.Series([.3, .6, .0, .1])
  2556. >>> s1.corr(s2, method=histogram_intersection)
  2557. 0.3
  2558. Pandas auto-aligns the values with matching indices
  2559. >>> s1 = pd.Series([1, 2, 3], index=[0, 1, 2])
  2560. >>> s2 = pd.Series([1, 2, 3], index=[2, 1, 0])
  2561. >>> s1.corr(s2)
  2562. -1.0
  2563. """ # noqa: E501
  2564. this, other = self.align(other, join="inner", copy=False)
  2565. if len(this) == 0:
  2566. return np.nan
  2567. this_values = this.to_numpy(dtype=float, na_value=np.nan, copy=False)
  2568. other_values = other.to_numpy(dtype=float, na_value=np.nan, copy=False)
  2569. if method in ["pearson", "spearman", "kendall"] or callable(method):
  2570. return nanops.nancorr(
  2571. this_values, other_values, method=method, min_periods=min_periods
  2572. )
  2573. raise ValueError(
  2574. "method must be either 'pearson', "
  2575. "'spearman', 'kendall', or a callable, "
  2576. f"'{method}' was supplied"
  2577. )
  2578. def cov(
  2579. self,
  2580. other: Series,
  2581. min_periods: int | None = None,
  2582. ddof: int | None = 1,
  2583. ) -> float:
  2584. """
  2585. Compute covariance with Series, excluding missing values.
  2586. The two `Series` objects are not required to be the same length and
  2587. will be aligned internally before the covariance is calculated.
  2588. Parameters
  2589. ----------
  2590. other : Series
  2591. Series with which to compute the covariance.
  2592. min_periods : int, optional
  2593. Minimum number of observations needed to have a valid result.
  2594. ddof : int, default 1
  2595. Delta degrees of freedom. The divisor used in calculations
  2596. is ``N - ddof``, where ``N`` represents the number of elements.
  2597. Returns
  2598. -------
  2599. float
  2600. Covariance between Series and other normalized by N-1
  2601. (unbiased estimator).
  2602. See Also
  2603. --------
  2604. DataFrame.cov : Compute pairwise covariance of columns.
  2605. Examples
  2606. --------
  2607. >>> s1 = pd.Series([0.90010907, 0.13484424, 0.62036035])
  2608. >>> s2 = pd.Series([0.12528585, 0.26962463, 0.51111198])
  2609. >>> s1.cov(s2)
  2610. -0.01685762652715874
  2611. """
  2612. this, other = self.align(other, join="inner", copy=False)
  2613. if len(this) == 0:
  2614. return np.nan
  2615. this_values = this.to_numpy(dtype=float, na_value=np.nan, copy=False)
  2616. other_values = other.to_numpy(dtype=float, na_value=np.nan, copy=False)
  2617. return nanops.nancov(
  2618. this_values, other_values, min_periods=min_periods, ddof=ddof
  2619. )
  2620. @doc(
  2621. klass="Series",
  2622. extra_params="",
  2623. other_klass="DataFrame",
  2624. examples=dedent(
  2625. """
  2626. Difference with previous row
  2627. >>> s = pd.Series([1, 1, 2, 3, 5, 8])
  2628. >>> s.diff()
  2629. 0 NaN
  2630. 1 0.0
  2631. 2 1.0
  2632. 3 1.0
  2633. 4 2.0
  2634. 5 3.0
  2635. dtype: float64
  2636. Difference with 3rd previous row
  2637. >>> s.diff(periods=3)
  2638. 0 NaN
  2639. 1 NaN
  2640. 2 NaN
  2641. 3 2.0
  2642. 4 4.0
  2643. 5 6.0
  2644. dtype: float64
  2645. Difference with following row
  2646. >>> s.diff(periods=-1)
  2647. 0 0.0
  2648. 1 -1.0
  2649. 2 -1.0
  2650. 3 -2.0
  2651. 4 -3.0
  2652. 5 NaN
  2653. dtype: float64
  2654. Overflow in input dtype
  2655. >>> s = pd.Series([1, 0], dtype=np.uint8)
  2656. >>> s.diff()
  2657. 0 NaN
  2658. 1 255.0
  2659. dtype: float64"""
  2660. ),
  2661. )
  2662. def diff(self, periods: int = 1) -> Series:
  2663. """
  2664. First discrete difference of element.
  2665. Calculates the difference of a {klass} element compared with another
  2666. element in the {klass} (default is element in previous row).
  2667. Parameters
  2668. ----------
  2669. periods : int, default 1
  2670. Periods to shift for calculating difference, accepts negative
  2671. values.
  2672. {extra_params}
  2673. Returns
  2674. -------
  2675. {klass}
  2676. First differences of the Series.
  2677. See Also
  2678. --------
  2679. {klass}.pct_change: Percent change over given number of periods.
  2680. {klass}.shift: Shift index by desired number of periods with an
  2681. optional time freq.
  2682. {other_klass}.diff: First discrete difference of object.
  2683. Notes
  2684. -----
  2685. For boolean dtypes, this uses :meth:`operator.xor` rather than
  2686. :meth:`operator.sub`.
  2687. The result is calculated according to current dtype in {klass},
  2688. however dtype of the result is always float64.
  2689. Examples
  2690. --------
  2691. {examples}
  2692. """
  2693. result = algorithms.diff(self._values, periods)
  2694. return self._constructor(result, index=self.index, copy=False).__finalize__(
  2695. self, method="diff"
  2696. )
  2697. def autocorr(self, lag: int = 1) -> float:
  2698. """
  2699. Compute the lag-N autocorrelation.
  2700. This method computes the Pearson correlation between
  2701. the Series and its shifted self.
  2702. Parameters
  2703. ----------
  2704. lag : int, default 1
  2705. Number of lags to apply before performing autocorrelation.
  2706. Returns
  2707. -------
  2708. float
  2709. The Pearson correlation between self and self.shift(lag).
  2710. See Also
  2711. --------
  2712. Series.corr : Compute the correlation between two Series.
  2713. Series.shift : Shift index by desired number of periods.
  2714. DataFrame.corr : Compute pairwise correlation of columns.
  2715. DataFrame.corrwith : Compute pairwise correlation between rows or
  2716. columns of two DataFrame objects.
  2717. Notes
  2718. -----
  2719. If the Pearson correlation is not well defined return 'NaN'.
  2720. Examples
  2721. --------
  2722. >>> s = pd.Series([0.25, 0.5, 0.2, -0.05])
  2723. >>> s.autocorr() # doctest: +ELLIPSIS
  2724. 0.10355...
  2725. >>> s.autocorr(lag=2) # doctest: +ELLIPSIS
  2726. -0.99999...
  2727. If the Pearson correlation is not well defined, then 'NaN' is returned.
  2728. >>> s = pd.Series([1, 0, 0, 0])
  2729. >>> s.autocorr()
  2730. nan
  2731. """
  2732. return self.corr(cast(Series, self.shift(lag)))
  2733. def dot(self, other: AnyArrayLike) -> Series | np.ndarray:
  2734. """
  2735. Compute the dot product between the Series and the columns of other.
  2736. This method computes the dot product between the Series and another
  2737. one, or the Series and each columns of a DataFrame, or the Series and
  2738. each columns of an array.
  2739. It can also be called using `self @ other`.
  2740. Parameters
  2741. ----------
  2742. other : Series, DataFrame or array-like
  2743. The other object to compute the dot product with its columns.
  2744. Returns
  2745. -------
  2746. scalar, Series or numpy.ndarray
  2747. Return the dot product of the Series and other if other is a
  2748. Series, the Series of the dot product of Series and each rows of
  2749. other if other is a DataFrame or a numpy.ndarray between the Series
  2750. and each columns of the numpy array.
  2751. See Also
  2752. --------
  2753. DataFrame.dot: Compute the matrix product with the DataFrame.
  2754. Series.mul: Multiplication of series and other, element-wise.
  2755. Notes
  2756. -----
  2757. The Series and other has to share the same index if other is a Series
  2758. or a DataFrame.
  2759. Examples
  2760. --------
  2761. >>> s = pd.Series([0, 1, 2, 3])
  2762. >>> other = pd.Series([-1, 2, -3, 4])
  2763. >>> s.dot(other)
  2764. 8
  2765. >>> s @ other
  2766. 8
  2767. >>> df = pd.DataFrame([[0, 1], [-2, 3], [4, -5], [6, 7]])
  2768. >>> s.dot(df)
  2769. 0 24
  2770. 1 14
  2771. dtype: int64
  2772. >>> arr = np.array([[0, 1], [-2, 3], [4, -5], [6, 7]])
  2773. >>> s.dot(arr)
  2774. array([24, 14])
  2775. """
  2776. if isinstance(other, (Series, ABCDataFrame)):
  2777. common = self.index.union(other.index)
  2778. if len(common) > len(self.index) or len(common) > len(other.index):
  2779. raise ValueError("matrices are not aligned")
  2780. left = self.reindex(index=common, copy=False)
  2781. right = other.reindex(index=common, copy=False)
  2782. lvals = left.values
  2783. rvals = right.values
  2784. else:
  2785. lvals = self.values
  2786. rvals = np.asarray(other)
  2787. if lvals.shape[0] != rvals.shape[0]:
  2788. raise Exception(
  2789. f"Dot product shape mismatch, {lvals.shape} vs {rvals.shape}"
  2790. )
  2791. if isinstance(other, ABCDataFrame):
  2792. return self._constructor(
  2793. np.dot(lvals, rvals), index=other.columns, copy=False
  2794. ).__finalize__(self, method="dot")
  2795. elif isinstance(other, Series):
  2796. return np.dot(lvals, rvals)
  2797. elif isinstance(rvals, np.ndarray):
  2798. return np.dot(lvals, rvals)
  2799. else: # pragma: no cover
  2800. raise TypeError(f"unsupported type: {type(other)}")
  2801. def __matmul__(self, other):
  2802. """
  2803. Matrix multiplication using binary `@` operator.
  2804. """
  2805. return self.dot(other)
  2806. def __rmatmul__(self, other):
  2807. """
  2808. Matrix multiplication using binary `@` operator.
  2809. """
  2810. return self.dot(np.transpose(other))
  2811. @doc(base.IndexOpsMixin.searchsorted, klass="Series")
  2812. # Signature of "searchsorted" incompatible with supertype "IndexOpsMixin"
  2813. def searchsorted( # type: ignore[override]
  2814. self,
  2815. value: NumpyValueArrayLike | ExtensionArray,
  2816. side: Literal["left", "right"] = "left",
  2817. sorter: NumpySorter | None = None,
  2818. ) -> npt.NDArray[np.intp] | np.intp:
  2819. return base.IndexOpsMixin.searchsorted(self, value, side=side, sorter=sorter)
  2820. # -------------------------------------------------------------------
  2821. # Combination
  2822. def _append(
  2823. self, to_append, ignore_index: bool = False, verify_integrity: bool = False
  2824. ):
  2825. from pandas.core.reshape.concat import concat
  2826. if isinstance(to_append, (list, tuple)):
  2827. to_concat = [self]
  2828. to_concat.extend(to_append)
  2829. else:
  2830. to_concat = [self, to_append]
  2831. if any(isinstance(x, (ABCDataFrame,)) for x in to_concat[1:]):
  2832. msg = "to_append should be a Series or list/tuple of Series, got DataFrame"
  2833. raise TypeError(msg)
  2834. return concat(
  2835. to_concat, ignore_index=ignore_index, verify_integrity=verify_integrity
  2836. )
  2837. @doc(
  2838. _shared_docs["compare"],
  2839. dedent(
  2840. """
  2841. Returns
  2842. -------
  2843. Series or DataFrame
  2844. If axis is 0 or 'index' the result will be a Series.
  2845. The resulting index will be a MultiIndex with 'self' and 'other'
  2846. stacked alternately at the inner level.
  2847. If axis is 1 or 'columns' the result will be a DataFrame.
  2848. It will have two columns namely 'self' and 'other'.
  2849. See Also
  2850. --------
  2851. DataFrame.compare : Compare with another DataFrame and show differences.
  2852. Notes
  2853. -----
  2854. Matching NaNs will not appear as a difference.
  2855. Examples
  2856. --------
  2857. >>> s1 = pd.Series(["a", "b", "c", "d", "e"])
  2858. >>> s2 = pd.Series(["a", "a", "c", "b", "e"])
  2859. Align the differences on columns
  2860. >>> s1.compare(s2)
  2861. self other
  2862. 1 b a
  2863. 3 d b
  2864. Stack the differences on indices
  2865. >>> s1.compare(s2, align_axis=0)
  2866. 1 self b
  2867. other a
  2868. 3 self d
  2869. other b
  2870. dtype: object
  2871. Keep all original rows
  2872. >>> s1.compare(s2, keep_shape=True)
  2873. self other
  2874. 0 NaN NaN
  2875. 1 b a
  2876. 2 NaN NaN
  2877. 3 d b
  2878. 4 NaN NaN
  2879. Keep all original rows and also all original values
  2880. >>> s1.compare(s2, keep_shape=True, keep_equal=True)
  2881. self other
  2882. 0 a a
  2883. 1 b a
  2884. 2 c c
  2885. 3 d b
  2886. 4 e e
  2887. """
  2888. ),
  2889. klass=_shared_doc_kwargs["klass"],
  2890. )
  2891. def compare(
  2892. self,
  2893. other: Series,
  2894. align_axis: Axis = 1,
  2895. keep_shape: bool = False,
  2896. keep_equal: bool = False,
  2897. result_names: Suffixes = ("self", "other"),
  2898. ) -> DataFrame | Series:
  2899. return super().compare(
  2900. other=other,
  2901. align_axis=align_axis,
  2902. keep_shape=keep_shape,
  2903. keep_equal=keep_equal,
  2904. result_names=result_names,
  2905. )
  2906. def combine(
  2907. self,
  2908. other: Series | Hashable,
  2909. func: Callable[[Hashable, Hashable], Hashable],
  2910. fill_value: Hashable | None = None,
  2911. ) -> Series:
  2912. """
  2913. Combine the Series with a Series or scalar according to `func`.
  2914. Combine the Series and `other` using `func` to perform elementwise
  2915. selection for combined Series.
  2916. `fill_value` is assumed when value is missing at some index
  2917. from one of the two objects being combined.
  2918. Parameters
  2919. ----------
  2920. other : Series or scalar
  2921. The value(s) to be combined with the `Series`.
  2922. func : function
  2923. Function that takes two scalars as inputs and returns an element.
  2924. fill_value : scalar, optional
  2925. The value to assume when an index is missing from
  2926. one Series or the other. The default specifies to use the
  2927. appropriate NaN value for the underlying dtype of the Series.
  2928. Returns
  2929. -------
  2930. Series
  2931. The result of combining the Series with the other object.
  2932. See Also
  2933. --------
  2934. Series.combine_first : Combine Series values, choosing the calling
  2935. Series' values first.
  2936. Examples
  2937. --------
  2938. Consider 2 Datasets ``s1`` and ``s2`` containing
  2939. highest clocked speeds of different birds.
  2940. >>> s1 = pd.Series({'falcon': 330.0, 'eagle': 160.0})
  2941. >>> s1
  2942. falcon 330.0
  2943. eagle 160.0
  2944. dtype: float64
  2945. >>> s2 = pd.Series({'falcon': 345.0, 'eagle': 200.0, 'duck': 30.0})
  2946. >>> s2
  2947. falcon 345.0
  2948. eagle 200.0
  2949. duck 30.0
  2950. dtype: float64
  2951. Now, to combine the two datasets and view the highest speeds
  2952. of the birds across the two datasets
  2953. >>> s1.combine(s2, max)
  2954. duck NaN
  2955. eagle 200.0
  2956. falcon 345.0
  2957. dtype: float64
  2958. In the previous example, the resulting value for duck is missing,
  2959. because the maximum of a NaN and a float is a NaN.
  2960. So, in the example, we set ``fill_value=0``,
  2961. so the maximum value returned will be the value from some dataset.
  2962. >>> s1.combine(s2, max, fill_value=0)
  2963. duck 30.0
  2964. eagle 200.0
  2965. falcon 345.0
  2966. dtype: float64
  2967. """
  2968. if fill_value is None:
  2969. fill_value = na_value_for_dtype(self.dtype, compat=False)
  2970. if isinstance(other, Series):
  2971. # If other is a Series, result is based on union of Series,
  2972. # so do this element by element
  2973. new_index = self.index.union(other.index)
  2974. new_name = ops.get_op_result_name(self, other)
  2975. new_values = np.empty(len(new_index), dtype=object)
  2976. with np.errstate(all="ignore"):
  2977. for i, idx in enumerate(new_index):
  2978. lv = self.get(idx, fill_value)
  2979. rv = other.get(idx, fill_value)
  2980. new_values[i] = func(lv, rv)
  2981. else:
  2982. # Assume that other is a scalar, so apply the function for
  2983. # each element in the Series
  2984. new_index = self.index
  2985. new_values = np.empty(len(new_index), dtype=object)
  2986. with np.errstate(all="ignore"):
  2987. new_values[:] = [func(lv, other) for lv in self._values]
  2988. new_name = self.name
  2989. # try_float=False is to match agg_series
  2990. npvalues = lib.maybe_convert_objects(new_values, try_float=False)
  2991. # same_dtype here is a kludge to avoid casting e.g. [True, False] to
  2992. # ["True", "False"]
  2993. same_dtype = isinstance(self.dtype, (StringDtype, CategoricalDtype))
  2994. res_values = maybe_cast_pointwise_result(
  2995. npvalues, self.dtype, same_dtype=same_dtype
  2996. )
  2997. return self._constructor(res_values, index=new_index, name=new_name, copy=False)
  2998. def combine_first(self, other) -> Series:
  2999. """
  3000. Update null elements with value in the same location in 'other'.
  3001. Combine two Series objects by filling null values in one Series with
  3002. non-null values from the other Series. Result index will be the union
  3003. of the two indexes.
  3004. Parameters
  3005. ----------
  3006. other : Series
  3007. The value(s) to be used for filling null values.
  3008. Returns
  3009. -------
  3010. Series
  3011. The result of combining the provided Series with the other object.
  3012. See Also
  3013. --------
  3014. Series.combine : Perform element-wise operation on two Series
  3015. using a given function.
  3016. Examples
  3017. --------
  3018. >>> s1 = pd.Series([1, np.nan])
  3019. >>> s2 = pd.Series([3, 4, 5])
  3020. >>> s1.combine_first(s2)
  3021. 0 1.0
  3022. 1 4.0
  3023. 2 5.0
  3024. dtype: float64
  3025. Null values still persist if the location of that null value
  3026. does not exist in `other`
  3027. >>> s1 = pd.Series({'falcon': np.nan, 'eagle': 160.0})
  3028. >>> s2 = pd.Series({'eagle': 200.0, 'duck': 30.0})
  3029. >>> s1.combine_first(s2)
  3030. duck 30.0
  3031. eagle 160.0
  3032. falcon NaN
  3033. dtype: float64
  3034. """
  3035. from pandas.core.reshape.concat import concat
  3036. if self.dtype == other.dtype:
  3037. if self.index.equals(other.index):
  3038. return self.mask(self.isna(), other)
  3039. elif self._can_hold_na and not isinstance(self.dtype, SparseDtype):
  3040. this, other = self.align(other, join="outer")
  3041. return this.mask(this.isna(), other)
  3042. new_index = self.index.union(other.index)
  3043. this = self
  3044. # identify the index subset to keep for each series
  3045. keep_other = other.index.difference(this.index[notna(this)])
  3046. keep_this = this.index.difference(keep_other)
  3047. this = this.reindex(keep_this, copy=False)
  3048. other = other.reindex(keep_other, copy=False)
  3049. if this.dtype.kind == "M" and other.dtype.kind != "M":
  3050. other = to_datetime(other)
  3051. combined = concat([this, other])
  3052. combined = combined.reindex(new_index, copy=False)
  3053. return combined.__finalize__(self, method="combine_first")
  3054. def update(self, other: Series | Sequence | Mapping) -> None:
  3055. """
  3056. Modify Series in place using values from passed Series.
  3057. Uses non-NA values from passed Series to make updates. Aligns
  3058. on index.
  3059. Parameters
  3060. ----------
  3061. other : Series, or object coercible into Series
  3062. Examples
  3063. --------
  3064. >>> s = pd.Series([1, 2, 3])
  3065. >>> s.update(pd.Series([4, 5, 6]))
  3066. >>> s
  3067. 0 4
  3068. 1 5
  3069. 2 6
  3070. dtype: int64
  3071. >>> s = pd.Series(['a', 'b', 'c'])
  3072. >>> s.update(pd.Series(['d', 'e'], index=[0, 2]))
  3073. >>> s
  3074. 0 d
  3075. 1 b
  3076. 2 e
  3077. dtype: object
  3078. >>> s = pd.Series([1, 2, 3])
  3079. >>> s.update(pd.Series([4, 5, 6, 7, 8]))
  3080. >>> s
  3081. 0 4
  3082. 1 5
  3083. 2 6
  3084. dtype: int64
  3085. If ``other`` contains NaNs the corresponding values are not updated
  3086. in the original Series.
  3087. >>> s = pd.Series([1, 2, 3])
  3088. >>> s.update(pd.Series([4, np.nan, 6]))
  3089. >>> s
  3090. 0 4
  3091. 1 2
  3092. 2 6
  3093. dtype: int64
  3094. ``other`` can also be a non-Series object type
  3095. that is coercible into a Series
  3096. >>> s = pd.Series([1, 2, 3])
  3097. >>> s.update([4, np.nan, 6])
  3098. >>> s
  3099. 0 4
  3100. 1 2
  3101. 2 6
  3102. dtype: int64
  3103. >>> s = pd.Series([1, 2, 3])
  3104. >>> s.update({1: 9})
  3105. >>> s
  3106. 0 1
  3107. 1 9
  3108. 2 3
  3109. dtype: int64
  3110. """
  3111. if not PYPY and not WARNING_CHECK_DISABLED and using_copy_on_write():
  3112. if sys.getrefcount(self) <= REF_COUNT:
  3113. warnings.warn(
  3114. _chained_assignment_method_msg,
  3115. ChainedAssignmentError,
  3116. stacklevel=2,
  3117. )
  3118. elif (
  3119. not PYPY
  3120. and not WARNING_CHECK_DISABLED
  3121. and not using_copy_on_write()
  3122. and self._is_view_after_cow_rules()
  3123. ):
  3124. ctr = sys.getrefcount(self)
  3125. ref_count = REF_COUNT
  3126. if _check_cacher(self):
  3127. # see https://github.com/pandas-dev/pandas/pull/56060#discussion_r1399245221
  3128. ref_count += 1
  3129. if ctr <= ref_count:
  3130. warnings.warn(
  3131. _chained_assignment_warning_method_msg,
  3132. FutureWarning,
  3133. stacklevel=2,
  3134. )
  3135. if not isinstance(other, Series):
  3136. other = Series(other)
  3137. other = other.reindex_like(self)
  3138. mask = notna(other)
  3139. self._mgr = self._mgr.putmask(mask=mask, new=other)
  3140. self._maybe_update_cacher()
  3141. # ----------------------------------------------------------------------
  3142. # Reindexing, sorting
  3143. @overload
  3144. def sort_values(
  3145. self,
  3146. *,
  3147. axis: Axis = ...,
  3148. ascending: bool | Sequence[bool] = ...,
  3149. inplace: Literal[False] = ...,
  3150. kind: SortKind = ...,
  3151. na_position: NaPosition = ...,
  3152. ignore_index: bool = ...,
  3153. key: ValueKeyFunc = ...,
  3154. ) -> Series:
  3155. ...
  3156. @overload
  3157. def sort_values(
  3158. self,
  3159. *,
  3160. axis: Axis = ...,
  3161. ascending: bool | Sequence[bool] = ...,
  3162. inplace: Literal[True],
  3163. kind: SortKind = ...,
  3164. na_position: NaPosition = ...,
  3165. ignore_index: bool = ...,
  3166. key: ValueKeyFunc = ...,
  3167. ) -> None:
  3168. ...
  3169. @overload
  3170. def sort_values(
  3171. self,
  3172. *,
  3173. axis: Axis = ...,
  3174. ascending: bool | Sequence[bool] = ...,
  3175. inplace: bool = ...,
  3176. kind: SortKind = ...,
  3177. na_position: NaPosition = ...,
  3178. ignore_index: bool = ...,
  3179. key: ValueKeyFunc = ...,
  3180. ) -> Series | None:
  3181. ...
  3182. def sort_values(
  3183. self,
  3184. *,
  3185. axis: Axis = 0,
  3186. ascending: bool | Sequence[bool] = True,
  3187. inplace: bool = False,
  3188. kind: SortKind = "quicksort",
  3189. na_position: NaPosition = "last",
  3190. ignore_index: bool = False,
  3191. key: ValueKeyFunc | None = None,
  3192. ) -> Series | None:
  3193. """
  3194. Sort by the values.
  3195. Sort a Series in ascending or descending order by some
  3196. criterion.
  3197. Parameters
  3198. ----------
  3199. axis : {0 or 'index'}
  3200. Unused. Parameter needed for compatibility with DataFrame.
  3201. ascending : bool or list of bools, default True
  3202. If True, sort values in ascending order, otherwise descending.
  3203. inplace : bool, default False
  3204. If True, perform operation in-place.
  3205. kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, default 'quicksort'
  3206. Choice of sorting algorithm. See also :func:`numpy.sort` for more
  3207. information. 'mergesort' and 'stable' are the only stable algorithms.
  3208. na_position : {'first' or 'last'}, default 'last'
  3209. Argument 'first' puts NaNs at the beginning, 'last' puts NaNs at
  3210. the end.
  3211. ignore_index : bool, default False
  3212. If True, the resulting axis will be labeled 0, 1, …, n - 1.
  3213. key : callable, optional
  3214. If not None, apply the key function to the series values
  3215. before sorting. This is similar to the `key` argument in the
  3216. builtin :meth:`sorted` function, with the notable difference that
  3217. this `key` function should be *vectorized*. It should expect a
  3218. ``Series`` and return an array-like.
  3219. Returns
  3220. -------
  3221. Series or None
  3222. Series ordered by values or None if ``inplace=True``.
  3223. See Also
  3224. --------
  3225. Series.sort_index : Sort by the Series indices.
  3226. DataFrame.sort_values : Sort DataFrame by the values along either axis.
  3227. DataFrame.sort_index : Sort DataFrame by indices.
  3228. Examples
  3229. --------
  3230. >>> s = pd.Series([np.nan, 1, 3, 10, 5])
  3231. >>> s
  3232. 0 NaN
  3233. 1 1.0
  3234. 2 3.0
  3235. 3 10.0
  3236. 4 5.0
  3237. dtype: float64
  3238. Sort values ascending order (default behaviour)
  3239. >>> s.sort_values(ascending=True)
  3240. 1 1.0
  3241. 2 3.0
  3242. 4 5.0
  3243. 3 10.0
  3244. 0 NaN
  3245. dtype: float64
  3246. Sort values descending order
  3247. >>> s.sort_values(ascending=False)
  3248. 3 10.0
  3249. 4 5.0
  3250. 2 3.0
  3251. 1 1.0
  3252. 0 NaN
  3253. dtype: float64
  3254. Sort values putting NAs first
  3255. >>> s.sort_values(na_position='first')
  3256. 0 NaN
  3257. 1 1.0
  3258. 2 3.0
  3259. 4 5.0
  3260. 3 10.0
  3261. dtype: float64
  3262. Sort a series of strings
  3263. >>> s = pd.Series(['z', 'b', 'd', 'a', 'c'])
  3264. >>> s
  3265. 0 z
  3266. 1 b
  3267. 2 d
  3268. 3 a
  3269. 4 c
  3270. dtype: object
  3271. >>> s.sort_values()
  3272. 3 a
  3273. 1 b
  3274. 4 c
  3275. 2 d
  3276. 0 z
  3277. dtype: object
  3278. Sort using a key function. Your `key` function will be
  3279. given the ``Series`` of values and should return an array-like.
  3280. >>> s = pd.Series(['a', 'B', 'c', 'D', 'e'])
  3281. >>> s.sort_values()
  3282. 1 B
  3283. 3 D
  3284. 0 a
  3285. 2 c
  3286. 4 e
  3287. dtype: object
  3288. >>> s.sort_values(key=lambda x: x.str.lower())
  3289. 0 a
  3290. 1 B
  3291. 2 c
  3292. 3 D
  3293. 4 e
  3294. dtype: object
  3295. NumPy ufuncs work well here. For example, we can
  3296. sort by the ``sin`` of the value
  3297. >>> s = pd.Series([-4, -2, 0, 2, 4])
  3298. >>> s.sort_values(key=np.sin)
  3299. 1 -2
  3300. 4 4
  3301. 2 0
  3302. 0 -4
  3303. 3 2
  3304. dtype: int64
  3305. More complicated user-defined functions can be used,
  3306. as long as they expect a Series and return an array-like
  3307. >>> s.sort_values(key=lambda x: (np.tan(x.cumsum())))
  3308. 0 -4
  3309. 3 2
  3310. 4 4
  3311. 1 -2
  3312. 2 0
  3313. dtype: int64
  3314. """
  3315. inplace = validate_bool_kwarg(inplace, "inplace")
  3316. # Validate the axis parameter
  3317. self._get_axis_number(axis)
  3318. # GH 5856/5853
  3319. if inplace and self._is_cached:
  3320. raise ValueError(
  3321. "This Series is a view of some other array, to "
  3322. "sort in-place you must create a copy"
  3323. )
  3324. if is_list_like(ascending):
  3325. ascending = cast(Sequence[bool], ascending)
  3326. if len(ascending) != 1:
  3327. raise ValueError(
  3328. f"Length of ascending ({len(ascending)}) must be 1 for Series"
  3329. )
  3330. ascending = ascending[0]
  3331. ascending = validate_ascending(ascending)
  3332. if na_position not in ["first", "last"]:
  3333. raise ValueError(f"invalid na_position: {na_position}")
  3334. # GH 35922. Make sorting stable by leveraging nargsort
  3335. if key:
  3336. values_to_sort = cast(Series, ensure_key_mapped(self, key))._values
  3337. else:
  3338. values_to_sort = self._values
  3339. sorted_index = nargsort(values_to_sort, kind, bool(ascending), na_position)
  3340. if is_range_indexer(sorted_index, len(sorted_index)):
  3341. if inplace:
  3342. return self._update_inplace(self)
  3343. return self.copy(deep=None)
  3344. result = self._constructor(
  3345. self._values[sorted_index], index=self.index[sorted_index], copy=False
  3346. )
  3347. if ignore_index:
  3348. result.index = default_index(len(sorted_index))
  3349. if not inplace:
  3350. return result.__finalize__(self, method="sort_values")
  3351. self._update_inplace(result)
  3352. return None
  3353. @overload
  3354. def sort_index(
  3355. self,
  3356. *,
  3357. axis: Axis = ...,
  3358. level: IndexLabel = ...,
  3359. ascending: bool | Sequence[bool] = ...,
  3360. inplace: Literal[True],
  3361. kind: SortKind = ...,
  3362. na_position: NaPosition = ...,
  3363. sort_remaining: bool = ...,
  3364. ignore_index: bool = ...,
  3365. key: IndexKeyFunc = ...,
  3366. ) -> None:
  3367. ...
  3368. @overload
  3369. def sort_index(
  3370. self,
  3371. *,
  3372. axis: Axis = ...,
  3373. level: IndexLabel = ...,
  3374. ascending: bool | Sequence[bool] = ...,
  3375. inplace: Literal[False] = ...,
  3376. kind: SortKind = ...,
  3377. na_position: NaPosition = ...,
  3378. sort_remaining: bool = ...,
  3379. ignore_index: bool = ...,
  3380. key: IndexKeyFunc = ...,
  3381. ) -> Series:
  3382. ...
  3383. @overload
  3384. def sort_index(
  3385. self,
  3386. *,
  3387. axis: Axis = ...,
  3388. level: IndexLabel = ...,
  3389. ascending: bool | Sequence[bool] = ...,
  3390. inplace: bool = ...,
  3391. kind: SortKind = ...,
  3392. na_position: NaPosition = ...,
  3393. sort_remaining: bool = ...,
  3394. ignore_index: bool = ...,
  3395. key: IndexKeyFunc = ...,
  3396. ) -> Series | None:
  3397. ...
  3398. def sort_index(
  3399. self,
  3400. *,
  3401. axis: Axis = 0,
  3402. level: IndexLabel | None = None,
  3403. ascending: bool | Sequence[bool] = True,
  3404. inplace: bool = False,
  3405. kind: SortKind = "quicksort",
  3406. na_position: NaPosition = "last",
  3407. sort_remaining: bool = True,
  3408. ignore_index: bool = False,
  3409. key: IndexKeyFunc | None = None,
  3410. ) -> Series | None:
  3411. """
  3412. Sort Series by index labels.
  3413. Returns a new Series sorted by label if `inplace` argument is
  3414. ``False``, otherwise updates the original series and returns None.
  3415. Parameters
  3416. ----------
  3417. axis : {0 or 'index'}
  3418. Unused. Parameter needed for compatibility with DataFrame.
  3419. level : int, optional
  3420. If not None, sort on values in specified index level(s).
  3421. ascending : bool or list-like of bools, default True
  3422. Sort ascending vs. descending. When the index is a MultiIndex the
  3423. sort direction can be controlled for each level individually.
  3424. inplace : bool, default False
  3425. If True, perform operation in-place.
  3426. kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, default 'quicksort'
  3427. Choice of sorting algorithm. See also :func:`numpy.sort` for more
  3428. information. 'mergesort' and 'stable' are the only stable algorithms. For
  3429. DataFrames, this option is only applied when sorting on a single
  3430. column or label.
  3431. na_position : {'first', 'last'}, default 'last'
  3432. If 'first' puts NaNs at the beginning, 'last' puts NaNs at the end.
  3433. Not implemented for MultiIndex.
  3434. sort_remaining : bool, default True
  3435. If True and sorting by level and index is multilevel, sort by other
  3436. levels too (in order) after sorting by specified level.
  3437. ignore_index : bool, default False
  3438. If True, the resulting axis will be labeled 0, 1, …, n - 1.
  3439. key : callable, optional
  3440. If not None, apply the key function to the index values
  3441. before sorting. This is similar to the `key` argument in the
  3442. builtin :meth:`sorted` function, with the notable difference that
  3443. this `key` function should be *vectorized*. It should expect an
  3444. ``Index`` and return an ``Index`` of the same shape.
  3445. Returns
  3446. -------
  3447. Series or None
  3448. The original Series sorted by the labels or None if ``inplace=True``.
  3449. See Also
  3450. --------
  3451. DataFrame.sort_index: Sort DataFrame by the index.
  3452. DataFrame.sort_values: Sort DataFrame by the value.
  3453. Series.sort_values : Sort Series by the value.
  3454. Examples
  3455. --------
  3456. >>> s = pd.Series(['a', 'b', 'c', 'd'], index=[3, 2, 1, 4])
  3457. >>> s.sort_index()
  3458. 1 c
  3459. 2 b
  3460. 3 a
  3461. 4 d
  3462. dtype: object
  3463. Sort Descending
  3464. >>> s.sort_index(ascending=False)
  3465. 4 d
  3466. 3 a
  3467. 2 b
  3468. 1 c
  3469. dtype: object
  3470. By default NaNs are put at the end, but use `na_position` to place
  3471. them at the beginning
  3472. >>> s = pd.Series(['a', 'b', 'c', 'd'], index=[3, 2, 1, np.nan])
  3473. >>> s.sort_index(na_position='first')
  3474. NaN d
  3475. 1.0 c
  3476. 2.0 b
  3477. 3.0 a
  3478. dtype: object
  3479. Specify index level to sort
  3480. >>> arrays = [np.array(['qux', 'qux', 'foo', 'foo',
  3481. ... 'baz', 'baz', 'bar', 'bar']),
  3482. ... np.array(['two', 'one', 'two', 'one',
  3483. ... 'two', 'one', 'two', 'one'])]
  3484. >>> s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8], index=arrays)
  3485. >>> s.sort_index(level=1)
  3486. bar one 8
  3487. baz one 6
  3488. foo one 4
  3489. qux one 2
  3490. bar two 7
  3491. baz two 5
  3492. foo two 3
  3493. qux two 1
  3494. dtype: int64
  3495. Does not sort by remaining levels when sorting by levels
  3496. >>> s.sort_index(level=1, sort_remaining=False)
  3497. qux one 2
  3498. foo one 4
  3499. baz one 6
  3500. bar one 8
  3501. qux two 1
  3502. foo two 3
  3503. baz two 5
  3504. bar two 7
  3505. dtype: int64
  3506. Apply a key function before sorting
  3507. >>> s = pd.Series([1, 2, 3, 4], index=['A', 'b', 'C', 'd'])
  3508. >>> s.sort_index(key=lambda x : x.str.lower())
  3509. A 1
  3510. b 2
  3511. C 3
  3512. d 4
  3513. dtype: int64
  3514. """
  3515. return super().sort_index(
  3516. axis=axis,
  3517. level=level,
  3518. ascending=ascending,
  3519. inplace=inplace,
  3520. kind=kind,
  3521. na_position=na_position,
  3522. sort_remaining=sort_remaining,
  3523. ignore_index=ignore_index,
  3524. key=key,
  3525. )
  3526. def argsort(
  3527. self,
  3528. axis: Axis = 0,
  3529. kind: SortKind = "quicksort",
  3530. order: None = None,
  3531. stable: None = None,
  3532. ) -> Series:
  3533. """
  3534. Return the integer indices that would sort the Series values.
  3535. Override ndarray.argsort. Argsorts the value, omitting NA/null values,
  3536. and places the result in the same locations as the non-NA values.
  3537. Parameters
  3538. ----------
  3539. axis : {0 or 'index'}
  3540. Unused. Parameter needed for compatibility with DataFrame.
  3541. kind : {'mergesort', 'quicksort', 'heapsort', 'stable'}, default 'quicksort'
  3542. Choice of sorting algorithm. See :func:`numpy.sort` for more
  3543. information. 'mergesort' and 'stable' are the only stable algorithms.
  3544. order : None
  3545. Has no effect but is accepted for compatibility with numpy.
  3546. stable : None
  3547. Has no effect but is accepted for compatibility with numpy.
  3548. Returns
  3549. -------
  3550. Series[np.intp]
  3551. Positions of values within the sort order with -1 indicating
  3552. nan values.
  3553. See Also
  3554. --------
  3555. numpy.ndarray.argsort : Returns the indices that would sort this array.
  3556. Examples
  3557. --------
  3558. >>> s = pd.Series([3, 2, 1])
  3559. >>> s.argsort()
  3560. 0 2
  3561. 1 1
  3562. 2 0
  3563. dtype: int64
  3564. """
  3565. if axis != -1:
  3566. # GH#54257 We allow -1 here so that np.argsort(series) works
  3567. self._get_axis_number(axis)
  3568. values = self._values
  3569. mask = isna(values)
  3570. if mask.any():
  3571. # TODO(3.0): once this deprecation is enforced we can call
  3572. # self.array.argsort directly, which will close GH#43840 and
  3573. # GH#12694
  3574. warnings.warn(
  3575. "The behavior of Series.argsort in the presence of NA values is "
  3576. "deprecated. In a future version, NA values will be ordered "
  3577. "last instead of set to -1.",
  3578. FutureWarning,
  3579. stacklevel=find_stack_level(),
  3580. )
  3581. result = np.full(len(self), -1, dtype=np.intp)
  3582. notmask = ~mask
  3583. result[notmask] = np.argsort(values[notmask], kind=kind)
  3584. else:
  3585. result = np.argsort(values, kind=kind)
  3586. res = self._constructor(
  3587. result, index=self.index, name=self.name, dtype=np.intp, copy=False
  3588. )
  3589. return res.__finalize__(self, method="argsort")
  3590. def nlargest(
  3591. self, n: int = 5, keep: Literal["first", "last", "all"] = "first"
  3592. ) -> Series:
  3593. """
  3594. Return the largest `n` elements.
  3595. Parameters
  3596. ----------
  3597. n : int, default 5
  3598. Return this many descending sorted values.
  3599. keep : {'first', 'last', 'all'}, default 'first'
  3600. When there are duplicate values that cannot all fit in a
  3601. Series of `n` elements:
  3602. - ``first`` : return the first `n` occurrences in order
  3603. of appearance.
  3604. - ``last`` : return the last `n` occurrences in reverse
  3605. order of appearance.
  3606. - ``all`` : keep all occurrences. This can result in a Series of
  3607. size larger than `n`.
  3608. Returns
  3609. -------
  3610. Series
  3611. The `n` largest values in the Series, sorted in decreasing order.
  3612. See Also
  3613. --------
  3614. Series.nsmallest: Get the `n` smallest elements.
  3615. Series.sort_values: Sort Series by values.
  3616. Series.head: Return the first `n` rows.
  3617. Notes
  3618. -----
  3619. Faster than ``.sort_values(ascending=False).head(n)`` for small `n`
  3620. relative to the size of the ``Series`` object.
  3621. Examples
  3622. --------
  3623. >>> countries_population = {"Italy": 59000000, "France": 65000000,
  3624. ... "Malta": 434000, "Maldives": 434000,
  3625. ... "Brunei": 434000, "Iceland": 337000,
  3626. ... "Nauru": 11300, "Tuvalu": 11300,
  3627. ... "Anguilla": 11300, "Montserrat": 5200}
  3628. >>> s = pd.Series(countries_population)
  3629. >>> s
  3630. Italy 59000000
  3631. France 65000000
  3632. Malta 434000
  3633. Maldives 434000
  3634. Brunei 434000
  3635. Iceland 337000
  3636. Nauru 11300
  3637. Tuvalu 11300
  3638. Anguilla 11300
  3639. Montserrat 5200
  3640. dtype: int64
  3641. The `n` largest elements where ``n=5`` by default.
  3642. >>> s.nlargest()
  3643. France 65000000
  3644. Italy 59000000
  3645. Malta 434000
  3646. Maldives 434000
  3647. Brunei 434000
  3648. dtype: int64
  3649. The `n` largest elements where ``n=3``. Default `keep` value is 'first'
  3650. so Malta will be kept.
  3651. >>> s.nlargest(3)
  3652. France 65000000
  3653. Italy 59000000
  3654. Malta 434000
  3655. dtype: int64
  3656. The `n` largest elements where ``n=3`` and keeping the last duplicates.
  3657. Brunei will be kept since it is the last with value 434000 based on
  3658. the index order.
  3659. >>> s.nlargest(3, keep='last')
  3660. France 65000000
  3661. Italy 59000000
  3662. Brunei 434000
  3663. dtype: int64
  3664. The `n` largest elements where ``n=3`` with all duplicates kept. Note
  3665. that the returned Series has five elements due to the three duplicates.
  3666. >>> s.nlargest(3, keep='all')
  3667. France 65000000
  3668. Italy 59000000
  3669. Malta 434000
  3670. Maldives 434000
  3671. Brunei 434000
  3672. dtype: int64
  3673. """
  3674. return selectn.SelectNSeries(self, n=n, keep=keep).nlargest()
  3675. def nsmallest(
  3676. self, n: int = 5, keep: Literal["first", "last", "all"] = "first"
  3677. ) -> Series:
  3678. """
  3679. Return the smallest `n` elements.
  3680. Parameters
  3681. ----------
  3682. n : int, default 5
  3683. Return this many ascending sorted values.
  3684. keep : {'first', 'last', 'all'}, default 'first'
  3685. When there are duplicate values that cannot all fit in a
  3686. Series of `n` elements:
  3687. - ``first`` : return the first `n` occurrences in order
  3688. of appearance.
  3689. - ``last`` : return the last `n` occurrences in reverse
  3690. order of appearance.
  3691. - ``all`` : keep all occurrences. This can result in a Series of
  3692. size larger than `n`.
  3693. Returns
  3694. -------
  3695. Series
  3696. The `n` smallest values in the Series, sorted in increasing order.
  3697. See Also
  3698. --------
  3699. Series.nlargest: Get the `n` largest elements.
  3700. Series.sort_values: Sort Series by values.
  3701. Series.head: Return the first `n` rows.
  3702. Notes
  3703. -----
  3704. Faster than ``.sort_values().head(n)`` for small `n` relative to
  3705. the size of the ``Series`` object.
  3706. Examples
  3707. --------
  3708. >>> countries_population = {"Italy": 59000000, "France": 65000000,
  3709. ... "Brunei": 434000, "Malta": 434000,
  3710. ... "Maldives": 434000, "Iceland": 337000,
  3711. ... "Nauru": 11300, "Tuvalu": 11300,
  3712. ... "Anguilla": 11300, "Montserrat": 5200}
  3713. >>> s = pd.Series(countries_population)
  3714. >>> s
  3715. Italy 59000000
  3716. France 65000000
  3717. Brunei 434000
  3718. Malta 434000
  3719. Maldives 434000
  3720. Iceland 337000
  3721. Nauru 11300
  3722. Tuvalu 11300
  3723. Anguilla 11300
  3724. Montserrat 5200
  3725. dtype: int64
  3726. The `n` smallest elements where ``n=5`` by default.
  3727. >>> s.nsmallest()
  3728. Montserrat 5200
  3729. Nauru 11300
  3730. Tuvalu 11300
  3731. Anguilla 11300
  3732. Iceland 337000
  3733. dtype: int64
  3734. The `n` smallest elements where ``n=3``. Default `keep` value is
  3735. 'first' so Nauru and Tuvalu will be kept.
  3736. >>> s.nsmallest(3)
  3737. Montserrat 5200
  3738. Nauru 11300
  3739. Tuvalu 11300
  3740. dtype: int64
  3741. The `n` smallest elements where ``n=3`` and keeping the last
  3742. duplicates. Anguilla and Tuvalu will be kept since they are the last
  3743. with value 11300 based on the index order.
  3744. >>> s.nsmallest(3, keep='last')
  3745. Montserrat 5200
  3746. Anguilla 11300
  3747. Tuvalu 11300
  3748. dtype: int64
  3749. The `n` smallest elements where ``n=3`` with all duplicates kept. Note
  3750. that the returned Series has four elements due to the three duplicates.
  3751. >>> s.nsmallest(3, keep='all')
  3752. Montserrat 5200
  3753. Nauru 11300
  3754. Tuvalu 11300
  3755. Anguilla 11300
  3756. dtype: int64
  3757. """
  3758. return selectn.SelectNSeries(self, n=n, keep=keep).nsmallest()
  3759. @doc(
  3760. klass=_shared_doc_kwargs["klass"],
  3761. extra_params=dedent(
  3762. """copy : bool, default True
  3763. Whether to copy underlying data.
  3764. .. note::
  3765. The `copy` keyword will change behavior in pandas 3.0.
  3766. `Copy-on-Write
  3767. <https://pandas.pydata.org/docs/dev/user_guide/copy_on_write.html>`__
  3768. will be enabled by default, which means that all methods with a
  3769. `copy` keyword will use a lazy copy mechanism to defer the copy and
  3770. ignore the `copy` keyword. The `copy` keyword will be removed in a
  3771. future version of pandas.
  3772. You can already get the future behavior and improvements through
  3773. enabling copy on write ``pd.options.mode.copy_on_write = True``"""
  3774. ),
  3775. examples=dedent(
  3776. """\
  3777. Examples
  3778. --------
  3779. >>> s = pd.Series(
  3780. ... ["A", "B", "A", "C"],
  3781. ... index=[
  3782. ... ["Final exam", "Final exam", "Coursework", "Coursework"],
  3783. ... ["History", "Geography", "History", "Geography"],
  3784. ... ["January", "February", "March", "April"],
  3785. ... ],
  3786. ... )
  3787. >>> s
  3788. Final exam History January A
  3789. Geography February B
  3790. Coursework History March A
  3791. Geography April C
  3792. dtype: object
  3793. In the following example, we will swap the levels of the indices.
  3794. Here, we will swap the levels column-wise, but levels can be swapped row-wise
  3795. in a similar manner. Note that column-wise is the default behaviour.
  3796. By not supplying any arguments for i and j, we swap the last and second to
  3797. last indices.
  3798. >>> s.swaplevel()
  3799. Final exam January History A
  3800. February Geography B
  3801. Coursework March History A
  3802. April Geography C
  3803. dtype: object
  3804. By supplying one argument, we can choose which index to swap the last
  3805. index with. We can for example swap the first index with the last one as
  3806. follows.
  3807. >>> s.swaplevel(0)
  3808. January History Final exam A
  3809. February Geography Final exam B
  3810. March History Coursework A
  3811. April Geography Coursework C
  3812. dtype: object
  3813. We can also define explicitly which indices we want to swap by supplying values
  3814. for both i and j. Here, we for example swap the first and second indices.
  3815. >>> s.swaplevel(0, 1)
  3816. History Final exam January A
  3817. Geography Final exam February B
  3818. History Coursework March A
  3819. Geography Coursework April C
  3820. dtype: object"""
  3821. ),
  3822. )
  3823. def swaplevel(
  3824. self, i: Level = -2, j: Level = -1, copy: bool | None = None
  3825. ) -> Series:
  3826. """
  3827. Swap levels i and j in a :class:`MultiIndex`.
  3828. Default is to swap the two innermost levels of the index.
  3829. Parameters
  3830. ----------
  3831. i, j : int or str
  3832. Levels of the indices to be swapped. Can pass level name as string.
  3833. {extra_params}
  3834. Returns
  3835. -------
  3836. {klass}
  3837. {klass} with levels swapped in MultiIndex.
  3838. {examples}
  3839. """
  3840. assert isinstance(self.index, MultiIndex)
  3841. result = self.copy(deep=copy and not using_copy_on_write())
  3842. result.index = self.index.swaplevel(i, j)
  3843. return result
  3844. def reorder_levels(self, order: Sequence[Level]) -> Series:
  3845. """
  3846. Rearrange index levels using input order.
  3847. May not drop or duplicate levels.
  3848. Parameters
  3849. ----------
  3850. order : list of int representing new level order
  3851. Reference level by number or key.
  3852. Returns
  3853. -------
  3854. type of caller (new object)
  3855. Examples
  3856. --------
  3857. >>> arrays = [np.array(["dog", "dog", "cat", "cat", "bird", "bird"]),
  3858. ... np.array(["white", "black", "white", "black", "white", "black"])]
  3859. >>> s = pd.Series([1, 2, 3, 3, 5, 2], index=arrays)
  3860. >>> s
  3861. dog white 1
  3862. black 2
  3863. cat white 3
  3864. black 3
  3865. bird white 5
  3866. black 2
  3867. dtype: int64
  3868. >>> s.reorder_levels([1, 0])
  3869. white dog 1
  3870. black dog 2
  3871. white cat 3
  3872. black cat 3
  3873. white bird 5
  3874. black bird 2
  3875. dtype: int64
  3876. """
  3877. if not isinstance(self.index, MultiIndex): # pragma: no cover
  3878. raise Exception("Can only reorder levels on a hierarchical axis.")
  3879. result = self.copy(deep=None)
  3880. assert isinstance(result.index, MultiIndex)
  3881. result.index = result.index.reorder_levels(order)
  3882. return result
  3883. def explode(self, ignore_index: bool = False) -> Series:
  3884. """
  3885. Transform each element of a list-like to a row.
  3886. Parameters
  3887. ----------
  3888. ignore_index : bool, default False
  3889. If True, the resulting index will be labeled 0, 1, …, n - 1.
  3890. Returns
  3891. -------
  3892. Series
  3893. Exploded lists to rows; index will be duplicated for these rows.
  3894. See Also
  3895. --------
  3896. Series.str.split : Split string values on specified separator.
  3897. Series.unstack : Unstack, a.k.a. pivot, Series with MultiIndex
  3898. to produce DataFrame.
  3899. DataFrame.melt : Unpivot a DataFrame from wide format to long format.
  3900. DataFrame.explode : Explode a DataFrame from list-like
  3901. columns to long format.
  3902. Notes
  3903. -----
  3904. This routine will explode list-likes including lists, tuples, sets,
  3905. Series, and np.ndarray. The result dtype of the subset rows will
  3906. be object. Scalars will be returned unchanged, and empty list-likes will
  3907. result in a np.nan for that row. In addition, the ordering of elements in
  3908. the output will be non-deterministic when exploding sets.
  3909. Reference :ref:`the user guide <reshaping.explode>` for more examples.
  3910. Examples
  3911. --------
  3912. >>> s = pd.Series([[1, 2, 3], 'foo', [], [3, 4]])
  3913. >>> s
  3914. 0 [1, 2, 3]
  3915. 1 foo
  3916. 2 []
  3917. 3 [3, 4]
  3918. dtype: object
  3919. >>> s.explode()
  3920. 0 1
  3921. 0 2
  3922. 0 3
  3923. 1 foo
  3924. 2 NaN
  3925. 3 3
  3926. 3 4
  3927. dtype: object
  3928. """
  3929. if isinstance(self.dtype, ExtensionDtype):
  3930. values, counts = self._values._explode()
  3931. elif len(self) and is_object_dtype(self.dtype):
  3932. values, counts = reshape.explode(np.asarray(self._values))
  3933. else:
  3934. result = self.copy()
  3935. return result.reset_index(drop=True) if ignore_index else result
  3936. if ignore_index:
  3937. index: Index = default_index(len(values))
  3938. else:
  3939. index = self.index.repeat(counts)
  3940. return self._constructor(values, index=index, name=self.name, copy=False)
  3941. def unstack(
  3942. self,
  3943. level: IndexLabel = -1,
  3944. fill_value: Hashable | None = None,
  3945. sort: bool = True,
  3946. ) -> DataFrame:
  3947. """
  3948. Unstack, also known as pivot, Series with MultiIndex to produce DataFrame.
  3949. Parameters
  3950. ----------
  3951. level : int, str, or list of these, default last level
  3952. Level(s) to unstack, can pass level name.
  3953. fill_value : scalar value, default None
  3954. Value to use when replacing NaN values.
  3955. sort : bool, default True
  3956. Sort the level(s) in the resulting MultiIndex columns.
  3957. Returns
  3958. -------
  3959. DataFrame
  3960. Unstacked Series.
  3961. Notes
  3962. -----
  3963. Reference :ref:`the user guide <reshaping.stacking>` for more examples.
  3964. Examples
  3965. --------
  3966. >>> s = pd.Series([1, 2, 3, 4],
  3967. ... index=pd.MultiIndex.from_product([['one', 'two'],
  3968. ... ['a', 'b']]))
  3969. >>> s
  3970. one a 1
  3971. b 2
  3972. two a 3
  3973. b 4
  3974. dtype: int64
  3975. >>> s.unstack(level=-1)
  3976. a b
  3977. one 1 2
  3978. two 3 4
  3979. >>> s.unstack(level=0)
  3980. one two
  3981. a 1 3
  3982. b 2 4
  3983. """
  3984. from pandas.core.reshape.reshape import unstack
  3985. return unstack(self, level, fill_value, sort)
  3986. # ----------------------------------------------------------------------
  3987. # function application
  3988. def map(
  3989. self,
  3990. arg: Callable | Mapping | Series,
  3991. na_action: Literal["ignore"] | None = None,
  3992. ) -> Series:
  3993. """
  3994. Map values of Series according to an input mapping or function.
  3995. Used for substituting each value in a Series with another value,
  3996. that may be derived from a function, a ``dict`` or
  3997. a :class:`Series`.
  3998. Parameters
  3999. ----------
  4000. arg : function, collections.abc.Mapping subclass or Series
  4001. Mapping correspondence.
  4002. na_action : {None, 'ignore'}, default None
  4003. If 'ignore', propagate NaN values, without passing them to the
  4004. mapping correspondence.
  4005. Returns
  4006. -------
  4007. Series
  4008. Same index as caller.
  4009. See Also
  4010. --------
  4011. Series.apply : For applying more complex functions on a Series.
  4012. Series.replace: Replace values given in `to_replace` with `value`.
  4013. DataFrame.apply : Apply a function row-/column-wise.
  4014. DataFrame.map : Apply a function elementwise on a whole DataFrame.
  4015. Notes
  4016. -----
  4017. When ``arg`` is a dictionary, values in Series that are not in the
  4018. dictionary (as keys) are converted to ``NaN``. However, if the
  4019. dictionary is a ``dict`` subclass that defines ``__missing__`` (i.e.
  4020. provides a method for default values), then this default is used
  4021. rather than ``NaN``.
  4022. Examples
  4023. --------
  4024. >>> s = pd.Series(['cat', 'dog', np.nan, 'rabbit'])
  4025. >>> s
  4026. 0 cat
  4027. 1 dog
  4028. 2 NaN
  4029. 3 rabbit
  4030. dtype: object
  4031. ``map`` accepts a ``dict`` or a ``Series``. Values that are not found
  4032. in the ``dict`` are converted to ``NaN``, unless the dict has a default
  4033. value (e.g. ``defaultdict``):
  4034. >>> s.map({'cat': 'kitten', 'dog': 'puppy'})
  4035. 0 kitten
  4036. 1 puppy
  4037. 2 NaN
  4038. 3 NaN
  4039. dtype: object
  4040. It also accepts a function:
  4041. >>> s.map('I am a {}'.format)
  4042. 0 I am a cat
  4043. 1 I am a dog
  4044. 2 I am a nan
  4045. 3 I am a rabbit
  4046. dtype: object
  4047. To avoid applying the function to missing values (and keep them as
  4048. ``NaN``) ``na_action='ignore'`` can be used:
  4049. >>> s.map('I am a {}'.format, na_action='ignore')
  4050. 0 I am a cat
  4051. 1 I am a dog
  4052. 2 NaN
  4053. 3 I am a rabbit
  4054. dtype: object
  4055. """
  4056. new_values = self._map_values(arg, na_action=na_action)
  4057. return self._constructor(new_values, index=self.index, copy=False).__finalize__(
  4058. self, method="map"
  4059. )
  4060. def _gotitem(self, key, ndim, subset=None) -> Self:
  4061. """
  4062. Sub-classes to define. Return a sliced object.
  4063. Parameters
  4064. ----------
  4065. key : string / list of selections
  4066. ndim : {1, 2}
  4067. Requested ndim of result.
  4068. subset : object, default None
  4069. Subset to act on.
  4070. """
  4071. return self
  4072. _agg_see_also_doc = dedent(
  4073. """
  4074. See Also
  4075. --------
  4076. Series.apply : Invoke function on a Series.
  4077. Series.transform : Transform function producing a Series with like indexes.
  4078. """
  4079. )
  4080. _agg_examples_doc = dedent(
  4081. """
  4082. Examples
  4083. --------
  4084. >>> s = pd.Series([1, 2, 3, 4])
  4085. >>> s
  4086. 0 1
  4087. 1 2
  4088. 2 3
  4089. 3 4
  4090. dtype: int64
  4091. >>> s.agg('min')
  4092. 1
  4093. >>> s.agg(['min', 'max'])
  4094. min 1
  4095. max 4
  4096. dtype: int64
  4097. """
  4098. )
  4099. @doc(
  4100. _shared_docs["aggregate"],
  4101. klass=_shared_doc_kwargs["klass"],
  4102. axis=_shared_doc_kwargs["axis"],
  4103. see_also=_agg_see_also_doc,
  4104. examples=_agg_examples_doc,
  4105. )
  4106. def aggregate(self, func=None, axis: Axis = 0, *args, **kwargs):
  4107. # Validate the axis parameter
  4108. self._get_axis_number(axis)
  4109. # if func is None, will switch to user-provided "named aggregation" kwargs
  4110. if func is None:
  4111. func = dict(kwargs.items())
  4112. op = SeriesApply(self, func, args=args, kwargs=kwargs)
  4113. result = op.agg()
  4114. return result
  4115. agg = aggregate
  4116. @doc(
  4117. _shared_docs["transform"],
  4118. klass=_shared_doc_kwargs["klass"],
  4119. axis=_shared_doc_kwargs["axis"],
  4120. )
  4121. def transform(
  4122. self, func: AggFuncType, axis: Axis = 0, *args, **kwargs
  4123. ) -> DataFrame | Series:
  4124. # Validate axis argument
  4125. self._get_axis_number(axis)
  4126. ser = (
  4127. self.copy(deep=False)
  4128. if using_copy_on_write() or warn_copy_on_write()
  4129. else self
  4130. )
  4131. result = SeriesApply(ser, func=func, args=args, kwargs=kwargs).transform()
  4132. return result
  4133. def apply(
  4134. self,
  4135. func: AggFuncType,
  4136. convert_dtype: bool | lib.NoDefault = lib.no_default,
  4137. args: tuple[Any, ...] = (),
  4138. *,
  4139. by_row: Literal[False, "compat"] = "compat",
  4140. **kwargs,
  4141. ) -> DataFrame | Series:
  4142. """
  4143. Invoke function on values of Series.
  4144. Can be ufunc (a NumPy function that applies to the entire Series)
  4145. or a Python function that only works on single values.
  4146. Parameters
  4147. ----------
  4148. func : function
  4149. Python function or NumPy ufunc to apply.
  4150. convert_dtype : bool, default True
  4151. Try to find better dtype for elementwise function results. If
  4152. False, leave as dtype=object. Note that the dtype is always
  4153. preserved for some extension array dtypes, such as Categorical.
  4154. .. deprecated:: 2.1.0
  4155. ``convert_dtype`` has been deprecated. Do ``ser.astype(object).apply()``
  4156. instead if you want ``convert_dtype=False``.
  4157. args : tuple
  4158. Positional arguments passed to func after the series value.
  4159. by_row : False or "compat", default "compat"
  4160. If ``"compat"`` and func is a callable, func will be passed each element of
  4161. the Series, like ``Series.map``. If func is a list or dict of
  4162. callables, will first try to translate each func into pandas methods. If
  4163. that doesn't work, will try call to apply again with ``by_row="compat"``
  4164. and if that fails, will call apply again with ``by_row=False``
  4165. (backward compatible).
  4166. If False, the func will be passed the whole Series at once.
  4167. ``by_row`` has no effect when ``func`` is a string.
  4168. .. versionadded:: 2.1.0
  4169. **kwargs
  4170. Additional keyword arguments passed to func.
  4171. Returns
  4172. -------
  4173. Series or DataFrame
  4174. If func returns a Series object the result will be a DataFrame.
  4175. See Also
  4176. --------
  4177. Series.map: For element-wise operations.
  4178. Series.agg: Only perform aggregating type operations.
  4179. Series.transform: Only perform transforming type operations.
  4180. Notes
  4181. -----
  4182. Functions that mutate the passed object can produce unexpected
  4183. behavior or errors and are not supported. See :ref:`gotchas.udf-mutation`
  4184. for more details.
  4185. Examples
  4186. --------
  4187. Create a series with typical summer temperatures for each city.
  4188. >>> s = pd.Series([20, 21, 12],
  4189. ... index=['London', 'New York', 'Helsinki'])
  4190. >>> s
  4191. London 20
  4192. New York 21
  4193. Helsinki 12
  4194. dtype: int64
  4195. Square the values by defining a function and passing it as an
  4196. argument to ``apply()``.
  4197. >>> def square(x):
  4198. ... return x ** 2
  4199. >>> s.apply(square)
  4200. London 400
  4201. New York 441
  4202. Helsinki 144
  4203. dtype: int64
  4204. Square the values by passing an anonymous function as an
  4205. argument to ``apply()``.
  4206. >>> s.apply(lambda x: x ** 2)
  4207. London 400
  4208. New York 441
  4209. Helsinki 144
  4210. dtype: int64
  4211. Define a custom function that needs additional positional
  4212. arguments and pass these additional arguments using the
  4213. ``args`` keyword.
  4214. >>> def subtract_custom_value(x, custom_value):
  4215. ... return x - custom_value
  4216. >>> s.apply(subtract_custom_value, args=(5,))
  4217. London 15
  4218. New York 16
  4219. Helsinki 7
  4220. dtype: int64
  4221. Define a custom function that takes keyword arguments
  4222. and pass these arguments to ``apply``.
  4223. >>> def add_custom_values(x, **kwargs):
  4224. ... for month in kwargs:
  4225. ... x += kwargs[month]
  4226. ... return x
  4227. >>> s.apply(add_custom_values, june=30, july=20, august=25)
  4228. London 95
  4229. New York 96
  4230. Helsinki 87
  4231. dtype: int64
  4232. Use a function from the Numpy library.
  4233. >>> s.apply(np.log)
  4234. London 2.995732
  4235. New York 3.044522
  4236. Helsinki 2.484907
  4237. dtype: float64
  4238. """
  4239. return SeriesApply(
  4240. self,
  4241. func,
  4242. convert_dtype=convert_dtype,
  4243. by_row=by_row,
  4244. args=args,
  4245. kwargs=kwargs,
  4246. ).apply()
  4247. def _reindex_indexer(
  4248. self,
  4249. new_index: Index | None,
  4250. indexer: npt.NDArray[np.intp] | None,
  4251. copy: bool | None,
  4252. ) -> Series:
  4253. # Note: new_index is None iff indexer is None
  4254. # if not None, indexer is np.intp
  4255. if indexer is None and (
  4256. new_index is None or new_index.names == self.index.names
  4257. ):
  4258. if using_copy_on_write():
  4259. return self.copy(deep=copy)
  4260. if copy or copy is None:
  4261. return self.copy(deep=copy)
  4262. return self
  4263. new_values = algorithms.take_nd(
  4264. self._values, indexer, allow_fill=True, fill_value=None
  4265. )
  4266. return self._constructor(new_values, index=new_index, copy=False)
  4267. def _needs_reindex_multi(self, axes, method, level) -> bool:
  4268. """
  4269. Check if we do need a multi reindex; this is for compat with
  4270. higher dims.
  4271. """
  4272. return False
  4273. @overload
  4274. def rename(
  4275. self,
  4276. index: Renamer | Hashable | None = ...,
  4277. *,
  4278. axis: Axis | None = ...,
  4279. copy: bool = ...,
  4280. inplace: Literal[True],
  4281. level: Level | None = ...,
  4282. errors: IgnoreRaise = ...,
  4283. ) -> None:
  4284. ...
  4285. @overload
  4286. def rename(
  4287. self,
  4288. index: Renamer | Hashable | None = ...,
  4289. *,
  4290. axis: Axis | None = ...,
  4291. copy: bool = ...,
  4292. inplace: Literal[False] = ...,
  4293. level: Level | None = ...,
  4294. errors: IgnoreRaise = ...,
  4295. ) -> Series:
  4296. ...
  4297. @overload
  4298. def rename(
  4299. self,
  4300. index: Renamer | Hashable | None = ...,
  4301. *,
  4302. axis: Axis | None = ...,
  4303. copy: bool = ...,
  4304. inplace: bool = ...,
  4305. level: Level | None = ...,
  4306. errors: IgnoreRaise = ...,
  4307. ) -> Series | None:
  4308. ...
  4309. def rename(
  4310. self,
  4311. index: Renamer | Hashable | None = None,
  4312. *,
  4313. axis: Axis | None = None,
  4314. copy: bool | None = None,
  4315. inplace: bool = False,
  4316. level: Level | None = None,
  4317. errors: IgnoreRaise = "ignore",
  4318. ) -> Series | None:
  4319. """
  4320. Alter Series index labels or name.
  4321. Function / dict values must be unique (1-to-1). Labels not contained in
  4322. a dict / Series will be left as-is. Extra labels listed don't throw an
  4323. error.
  4324. Alternatively, change ``Series.name`` with a scalar value.
  4325. See the :ref:`user guide <basics.rename>` for more.
  4326. Parameters
  4327. ----------
  4328. index : scalar, hashable sequence, dict-like or function optional
  4329. Functions or dict-like are transformations to apply to
  4330. the index.
  4331. Scalar or hashable sequence-like will alter the ``Series.name``
  4332. attribute.
  4333. axis : {0 or 'index'}
  4334. Unused. Parameter needed for compatibility with DataFrame.
  4335. copy : bool, default True
  4336. Also copy underlying data.
  4337. .. note::
  4338. The `copy` keyword will change behavior in pandas 3.0.
  4339. `Copy-on-Write
  4340. <https://pandas.pydata.org/docs/dev/user_guide/copy_on_write.html>`__
  4341. will be enabled by default, which means that all methods with a
  4342. `copy` keyword will use a lazy copy mechanism to defer the copy and
  4343. ignore the `copy` keyword. The `copy` keyword will be removed in a
  4344. future version of pandas.
  4345. You can already get the future behavior and improvements through
  4346. enabling copy on write ``pd.options.mode.copy_on_write = True``
  4347. inplace : bool, default False
  4348. Whether to return a new Series. If True the value of copy is ignored.
  4349. level : int or level name, default None
  4350. In case of MultiIndex, only rename labels in the specified level.
  4351. errors : {'ignore', 'raise'}, default 'ignore'
  4352. If 'raise', raise `KeyError` when a `dict-like mapper` or
  4353. `index` contains labels that are not present in the index being transformed.
  4354. If 'ignore', existing keys will be renamed and extra keys will be ignored.
  4355. Returns
  4356. -------
  4357. Series or None
  4358. Series with index labels or name altered or None if ``inplace=True``.
  4359. See Also
  4360. --------
  4361. DataFrame.rename : Corresponding DataFrame method.
  4362. Series.rename_axis : Set the name of the axis.
  4363. Examples
  4364. --------
  4365. >>> s = pd.Series([1, 2, 3])
  4366. >>> s
  4367. 0 1
  4368. 1 2
  4369. 2 3
  4370. dtype: int64
  4371. >>> s.rename("my_name") # scalar, changes Series.name
  4372. 0 1
  4373. 1 2
  4374. 2 3
  4375. Name: my_name, dtype: int64
  4376. >>> s.rename(lambda x: x ** 2) # function, changes labels
  4377. 0 1
  4378. 1 2
  4379. 4 3
  4380. dtype: int64
  4381. >>> s.rename({1: 3, 2: 5}) # mapping, changes labels
  4382. 0 1
  4383. 3 2
  4384. 5 3
  4385. dtype: int64
  4386. """
  4387. if axis is not None:
  4388. # Make sure we raise if an invalid 'axis' is passed.
  4389. axis = self._get_axis_number(axis)
  4390. if callable(index) or is_dict_like(index):
  4391. # error: Argument 1 to "_rename" of "NDFrame" has incompatible
  4392. # type "Union[Union[Mapping[Any, Hashable], Callable[[Any],
  4393. # Hashable]], Hashable, None]"; expected "Union[Mapping[Any,
  4394. # Hashable], Callable[[Any], Hashable], None]"
  4395. return super()._rename(
  4396. index, # type: ignore[arg-type]
  4397. copy=copy,
  4398. inplace=inplace,
  4399. level=level,
  4400. errors=errors,
  4401. )
  4402. else:
  4403. return self._set_name(index, inplace=inplace, deep=copy)
  4404. @Appender(
  4405. """
  4406. Examples
  4407. --------
  4408. >>> s = pd.Series([1, 2, 3])
  4409. >>> s
  4410. 0 1
  4411. 1 2
  4412. 2 3
  4413. dtype: int64
  4414. >>> s.set_axis(['a', 'b', 'c'], axis=0)
  4415. a 1
  4416. b 2
  4417. c 3
  4418. dtype: int64
  4419. """
  4420. )
  4421. @Substitution(
  4422. klass=_shared_doc_kwargs["klass"],
  4423. axes_single_arg=_shared_doc_kwargs["axes_single_arg"],
  4424. extended_summary_sub="",
  4425. axis_description_sub="",
  4426. see_also_sub="",
  4427. )
  4428. @Appender(NDFrame.set_axis.__doc__)
  4429. def set_axis(
  4430. self,
  4431. labels,
  4432. *,
  4433. axis: Axis = 0,
  4434. copy: bool | None = None,
  4435. ) -> Series:
  4436. return super().set_axis(labels, axis=axis, copy=copy)
  4437. # error: Cannot determine type of 'reindex'
  4438. @doc(
  4439. NDFrame.reindex, # type: ignore[has-type]
  4440. klass=_shared_doc_kwargs["klass"],
  4441. optional_reindex=_shared_doc_kwargs["optional_reindex"],
  4442. )
  4443. def reindex( # type: ignore[override]
  4444. self,
  4445. index=None,
  4446. *,
  4447. axis: Axis | None = None,
  4448. method: ReindexMethod | None = None,
  4449. copy: bool | None = None,
  4450. level: Level | None = None,
  4451. fill_value: Scalar | None = None,
  4452. limit: int | None = None,
  4453. tolerance=None,
  4454. ) -> Series:
  4455. return super().reindex(
  4456. index=index,
  4457. method=method,
  4458. copy=copy,
  4459. level=level,
  4460. fill_value=fill_value,
  4461. limit=limit,
  4462. tolerance=tolerance,
  4463. )
  4464. @overload # type: ignore[override]
  4465. def rename_axis(
  4466. self,
  4467. mapper: IndexLabel | lib.NoDefault = ...,
  4468. *,
  4469. index=...,
  4470. axis: Axis = ...,
  4471. copy: bool = ...,
  4472. inplace: Literal[True],
  4473. ) -> None:
  4474. ...
  4475. @overload
  4476. def rename_axis(
  4477. self,
  4478. mapper: IndexLabel | lib.NoDefault = ...,
  4479. *,
  4480. index=...,
  4481. axis: Axis = ...,
  4482. copy: bool = ...,
  4483. inplace: Literal[False] = ...,
  4484. ) -> Self:
  4485. ...
  4486. @overload
  4487. def rename_axis(
  4488. self,
  4489. mapper: IndexLabel | lib.NoDefault = ...,
  4490. *,
  4491. index=...,
  4492. axis: Axis = ...,
  4493. copy: bool = ...,
  4494. inplace: bool = ...,
  4495. ) -> Self | None:
  4496. ...
  4497. @doc(NDFrame.rename_axis)
  4498. def rename_axis(
  4499. self,
  4500. mapper: IndexLabel | lib.NoDefault = lib.no_default,
  4501. *,
  4502. index=lib.no_default,
  4503. axis: Axis = 0,
  4504. copy: bool = True,
  4505. inplace: bool = False,
  4506. ) -> Self | None:
  4507. return super().rename_axis(
  4508. mapper=mapper,
  4509. index=index,
  4510. axis=axis,
  4511. copy=copy,
  4512. inplace=inplace,
  4513. )
  4514. @overload
  4515. def drop(
  4516. self,
  4517. labels: IndexLabel = ...,
  4518. *,
  4519. axis: Axis = ...,
  4520. index: IndexLabel = ...,
  4521. columns: IndexLabel = ...,
  4522. level: Level | None = ...,
  4523. inplace: Literal[True],
  4524. errors: IgnoreRaise = ...,
  4525. ) -> None:
  4526. ...
  4527. @overload
  4528. def drop(
  4529. self,
  4530. labels: IndexLabel = ...,
  4531. *,
  4532. axis: Axis = ...,
  4533. index: IndexLabel = ...,
  4534. columns: IndexLabel = ...,
  4535. level: Level | None = ...,
  4536. inplace: Literal[False] = ...,
  4537. errors: IgnoreRaise = ...,
  4538. ) -> Series:
  4539. ...
  4540. @overload
  4541. def drop(
  4542. self,
  4543. labels: IndexLabel = ...,
  4544. *,
  4545. axis: Axis = ...,
  4546. index: IndexLabel = ...,
  4547. columns: IndexLabel = ...,
  4548. level: Level | None = ...,
  4549. inplace: bool = ...,
  4550. errors: IgnoreRaise = ...,
  4551. ) -> Series | None:
  4552. ...
  4553. def drop(
  4554. self,
  4555. labels: IndexLabel | None = None,
  4556. *,
  4557. axis: Axis = 0,
  4558. index: IndexLabel | None = None,
  4559. columns: IndexLabel | None = None,
  4560. level: Level | None = None,
  4561. inplace: bool = False,
  4562. errors: IgnoreRaise = "raise",
  4563. ) -> Series | None:
  4564. """
  4565. Return Series with specified index labels removed.
  4566. Remove elements of a Series based on specifying the index labels.
  4567. When using a multi-index, labels on different levels can be removed
  4568. by specifying the level.
  4569. Parameters
  4570. ----------
  4571. labels : single label or list-like
  4572. Index labels to drop.
  4573. axis : {0 or 'index'}
  4574. Unused. Parameter needed for compatibility with DataFrame.
  4575. index : single label or list-like
  4576. Redundant for application on Series, but 'index' can be used instead
  4577. of 'labels'.
  4578. columns : single label or list-like
  4579. No change is made to the Series; use 'index' or 'labels' instead.
  4580. level : int or level name, optional
  4581. For MultiIndex, level for which the labels will be removed.
  4582. inplace : bool, default False
  4583. If True, do operation inplace and return None.
  4584. errors : {'ignore', 'raise'}, default 'raise'
  4585. If 'ignore', suppress error and only existing labels are dropped.
  4586. Returns
  4587. -------
  4588. Series or None
  4589. Series with specified index labels removed or None if ``inplace=True``.
  4590. Raises
  4591. ------
  4592. KeyError
  4593. If none of the labels are found in the index.
  4594. See Also
  4595. --------
  4596. Series.reindex : Return only specified index labels of Series.
  4597. Series.dropna : Return series without null values.
  4598. Series.drop_duplicates : Return Series with duplicate values removed.
  4599. DataFrame.drop : Drop specified labels from rows or columns.
  4600. Examples
  4601. --------
  4602. >>> s = pd.Series(data=np.arange(3), index=['A', 'B', 'C'])
  4603. >>> s
  4604. A 0
  4605. B 1
  4606. C 2
  4607. dtype: int64
  4608. Drop labels B en C
  4609. >>> s.drop(labels=['B', 'C'])
  4610. A 0
  4611. dtype: int64
  4612. Drop 2nd level label in MultiIndex Series
  4613. >>> midx = pd.MultiIndex(levels=[['llama', 'cow', 'falcon'],
  4614. ... ['speed', 'weight', 'length']],
  4615. ... codes=[[0, 0, 0, 1, 1, 1, 2, 2, 2],
  4616. ... [0, 1, 2, 0, 1, 2, 0, 1, 2]])
  4617. >>> s = pd.Series([45, 200, 1.2, 30, 250, 1.5, 320, 1, 0.3],
  4618. ... index=midx)
  4619. >>> s
  4620. llama speed 45.0
  4621. weight 200.0
  4622. length 1.2
  4623. cow speed 30.0
  4624. weight 250.0
  4625. length 1.5
  4626. falcon speed 320.0
  4627. weight 1.0
  4628. length 0.3
  4629. dtype: float64
  4630. >>> s.drop(labels='weight', level=1)
  4631. llama speed 45.0
  4632. length 1.2
  4633. cow speed 30.0
  4634. length 1.5
  4635. falcon speed 320.0
  4636. length 0.3
  4637. dtype: float64
  4638. """
  4639. return super().drop(
  4640. labels=labels,
  4641. axis=axis,
  4642. index=index,
  4643. columns=columns,
  4644. level=level,
  4645. inplace=inplace,
  4646. errors=errors,
  4647. )
  4648. def pop(self, item: Hashable) -> Any:
  4649. """
  4650. Return item and drops from series. Raise KeyError if not found.
  4651. Parameters
  4652. ----------
  4653. item : label
  4654. Index of the element that needs to be removed.
  4655. Returns
  4656. -------
  4657. Value that is popped from series.
  4658. Examples
  4659. --------
  4660. >>> ser = pd.Series([1, 2, 3])
  4661. >>> ser.pop(0)
  4662. 1
  4663. >>> ser
  4664. 1 2
  4665. 2 3
  4666. dtype: int64
  4667. """
  4668. return super().pop(item=item)
  4669. @doc(INFO_DOCSTRING, **series_sub_kwargs)
  4670. def info(
  4671. self,
  4672. verbose: bool | None = None,
  4673. buf: IO[str] | None = None,
  4674. max_cols: int | None = None,
  4675. memory_usage: bool | str | None = None,
  4676. show_counts: bool = True,
  4677. ) -> None:
  4678. return SeriesInfo(self, memory_usage).render(
  4679. buf=buf,
  4680. max_cols=max_cols,
  4681. verbose=verbose,
  4682. show_counts=show_counts,
  4683. )
  4684. # TODO(3.0): this can be removed once GH#33302 deprecation is enforced
  4685. def _replace_single(self, to_replace, method: str, inplace: bool, limit):
  4686. """
  4687. Replaces values in a Series using the fill method specified when no
  4688. replacement value is given in the replace method
  4689. """
  4690. result = self if inplace else self.copy()
  4691. values = result._values
  4692. mask = missing.mask_missing(values, to_replace)
  4693. if isinstance(values, ExtensionArray):
  4694. # dispatch to the EA's _pad_mask_inplace method
  4695. values._fill_mask_inplace(method, limit, mask)
  4696. else:
  4697. fill_f = missing.get_fill_func(method)
  4698. fill_f(values, limit=limit, mask=mask)
  4699. if inplace:
  4700. return
  4701. return result
  4702. def memory_usage(self, index: bool = True, deep: bool = False) -> int:
  4703. """
  4704. Return the memory usage of the Series.
  4705. The memory usage can optionally include the contribution of
  4706. the index and of elements of `object` dtype.
  4707. Parameters
  4708. ----------
  4709. index : bool, default True
  4710. Specifies whether to include the memory usage of the Series index.
  4711. deep : bool, default False
  4712. If True, introspect the data deeply by interrogating
  4713. `object` dtypes for system-level memory consumption, and include
  4714. it in the returned value.
  4715. Returns
  4716. -------
  4717. int
  4718. Bytes of memory consumed.
  4719. See Also
  4720. --------
  4721. numpy.ndarray.nbytes : Total bytes consumed by the elements of the
  4722. array.
  4723. DataFrame.memory_usage : Bytes consumed by a DataFrame.
  4724. Examples
  4725. --------
  4726. >>> s = pd.Series(range(3))
  4727. >>> s.memory_usage()
  4728. 152
  4729. Not including the index gives the size of the rest of the data, which
  4730. is necessarily smaller:
  4731. >>> s.memory_usage(index=False)
  4732. 24
  4733. The memory footprint of `object` values is ignored by default:
  4734. >>> s = pd.Series(["a", "b"])
  4735. >>> s.values
  4736. array(['a', 'b'], dtype=object)
  4737. >>> s.memory_usage()
  4738. 144
  4739. >>> s.memory_usage(deep=True)
  4740. 244
  4741. """
  4742. v = self._memory_usage(deep=deep)
  4743. if index:
  4744. v += self.index.memory_usage(deep=deep)
  4745. return v
  4746. def isin(self, values) -> Series:
  4747. """
  4748. Whether elements in Series are contained in `values`.
  4749. Return a boolean Series showing whether each element in the Series
  4750. matches an element in the passed sequence of `values` exactly.
  4751. Parameters
  4752. ----------
  4753. values : set or list-like
  4754. The sequence of values to test. Passing in a single string will
  4755. raise a ``TypeError``. Instead, turn a single string into a
  4756. list of one element.
  4757. Returns
  4758. -------
  4759. Series
  4760. Series of booleans indicating if each element is in values.
  4761. Raises
  4762. ------
  4763. TypeError
  4764. * If `values` is a string
  4765. See Also
  4766. --------
  4767. DataFrame.isin : Equivalent method on DataFrame.
  4768. Examples
  4769. --------
  4770. >>> s = pd.Series(['llama', 'cow', 'llama', 'beetle', 'llama',
  4771. ... 'hippo'], name='animal')
  4772. >>> s.isin(['cow', 'llama'])
  4773. 0 True
  4774. 1 True
  4775. 2 True
  4776. 3 False
  4777. 4 True
  4778. 5 False
  4779. Name: animal, dtype: bool
  4780. To invert the boolean values, use the ``~`` operator:
  4781. >>> ~s.isin(['cow', 'llama'])
  4782. 0 False
  4783. 1 False
  4784. 2 False
  4785. 3 True
  4786. 4 False
  4787. 5 True
  4788. Name: animal, dtype: bool
  4789. Passing a single string as ``s.isin('llama')`` will raise an error. Use
  4790. a list of one element instead:
  4791. >>> s.isin(['llama'])
  4792. 0 True
  4793. 1 False
  4794. 2 True
  4795. 3 False
  4796. 4 True
  4797. 5 False
  4798. Name: animal, dtype: bool
  4799. Strings and integers are distinct and are therefore not comparable:
  4800. >>> pd.Series([1]).isin(['1'])
  4801. 0 False
  4802. dtype: bool
  4803. >>> pd.Series([1.1]).isin(['1.1'])
  4804. 0 False
  4805. dtype: bool
  4806. """
  4807. result = algorithms.isin(self._values, values)
  4808. return self._constructor(result, index=self.index, copy=False).__finalize__(
  4809. self, method="isin"
  4810. )
  4811. def between(
  4812. self,
  4813. left,
  4814. right,
  4815. inclusive: Literal["both", "neither", "left", "right"] = "both",
  4816. ) -> Series:
  4817. """
  4818. Return boolean Series equivalent to left <= series <= right.
  4819. This function returns a boolean vector containing `True` wherever the
  4820. corresponding Series element is between the boundary values `left` and
  4821. `right`. NA values are treated as `False`.
  4822. Parameters
  4823. ----------
  4824. left : scalar or list-like
  4825. Left boundary.
  4826. right : scalar or list-like
  4827. Right boundary.
  4828. inclusive : {"both", "neither", "left", "right"}
  4829. Include boundaries. Whether to set each bound as closed or open.
  4830. .. versionchanged:: 1.3.0
  4831. Returns
  4832. -------
  4833. Series
  4834. Series representing whether each element is between left and
  4835. right (inclusive).
  4836. See Also
  4837. --------
  4838. Series.gt : Greater than of series and other.
  4839. Series.lt : Less than of series and other.
  4840. Notes
  4841. -----
  4842. This function is equivalent to ``(left <= ser) & (ser <= right)``
  4843. Examples
  4844. --------
  4845. >>> s = pd.Series([2, 0, 4, 8, np.nan])
  4846. Boundary values are included by default:
  4847. >>> s.between(1, 4)
  4848. 0 True
  4849. 1 False
  4850. 2 True
  4851. 3 False
  4852. 4 False
  4853. dtype: bool
  4854. With `inclusive` set to ``"neither"`` boundary values are excluded:
  4855. >>> s.between(1, 4, inclusive="neither")
  4856. 0 True
  4857. 1 False
  4858. 2 False
  4859. 3 False
  4860. 4 False
  4861. dtype: bool
  4862. `left` and `right` can be any scalar value:
  4863. >>> s = pd.Series(['Alice', 'Bob', 'Carol', 'Eve'])
  4864. >>> s.between('Anna', 'Daniel')
  4865. 0 False
  4866. 1 True
  4867. 2 True
  4868. 3 False
  4869. dtype: bool
  4870. """
  4871. if inclusive == "both":
  4872. lmask = self >= left
  4873. rmask = self <= right
  4874. elif inclusive == "left":
  4875. lmask = self >= left
  4876. rmask = self < right
  4877. elif inclusive == "right":
  4878. lmask = self > left
  4879. rmask = self <= right
  4880. elif inclusive == "neither":
  4881. lmask = self > left
  4882. rmask = self < right
  4883. else:
  4884. raise ValueError(
  4885. "Inclusive has to be either string of 'both',"
  4886. "'left', 'right', or 'neither'."
  4887. )
  4888. return lmask & rmask
  4889. def case_when(
  4890. self,
  4891. caselist: list[
  4892. tuple[
  4893. ArrayLike | Callable[[Series], Series | np.ndarray | Sequence[bool]],
  4894. ArrayLike | Scalar | Callable[[Series], Series | np.ndarray],
  4895. ],
  4896. ],
  4897. ) -> Series:
  4898. """
  4899. Replace values where the conditions are True.
  4900. Parameters
  4901. ----------
  4902. caselist : A list of tuples of conditions and expected replacements
  4903. Takes the form: ``(condition0, replacement0)``,
  4904. ``(condition1, replacement1)``, ... .
  4905. ``condition`` should be a 1-D boolean array-like object
  4906. or a callable. If ``condition`` is a callable,
  4907. it is computed on the Series
  4908. and should return a boolean Series or array.
  4909. The callable must not change the input Series
  4910. (though pandas doesn`t check it). ``replacement`` should be a
  4911. 1-D array-like object, a scalar or a callable.
  4912. If ``replacement`` is a callable, it is computed on the Series
  4913. and should return a scalar or Series. The callable
  4914. must not change the input Series
  4915. (though pandas doesn`t check it).
  4916. .. versionadded:: 2.2.0
  4917. Returns
  4918. -------
  4919. Series
  4920. See Also
  4921. --------
  4922. Series.mask : Replace values where the condition is True.
  4923. Examples
  4924. --------
  4925. >>> c = pd.Series([6, 7, 8, 9], name='c')
  4926. >>> a = pd.Series([0, 0, 1, 2])
  4927. >>> b = pd.Series([0, 3, 4, 5])
  4928. >>> c.case_when(caselist=[(a.gt(0), a), # condition, replacement
  4929. ... (b.gt(0), b)])
  4930. 0 6
  4931. 1 3
  4932. 2 1
  4933. 3 2
  4934. Name: c, dtype: int64
  4935. """
  4936. if not isinstance(caselist, list):
  4937. raise TypeError(
  4938. f"The caselist argument should be a list; instead got {type(caselist)}"
  4939. )
  4940. if not caselist:
  4941. raise ValueError(
  4942. "provide at least one boolean condition, "
  4943. "with a corresponding replacement."
  4944. )
  4945. for num, entry in enumerate(caselist):
  4946. if not isinstance(entry, tuple):
  4947. raise TypeError(
  4948. f"Argument {num} must be a tuple; instead got {type(entry)}."
  4949. )
  4950. if len(entry) != 2:
  4951. raise ValueError(
  4952. f"Argument {num} must have length 2; "
  4953. "a condition and replacement; "
  4954. f"instead got length {len(entry)}."
  4955. )
  4956. caselist = [
  4957. (
  4958. com.apply_if_callable(condition, self),
  4959. com.apply_if_callable(replacement, self),
  4960. )
  4961. for condition, replacement in caselist
  4962. ]
  4963. default = self.copy()
  4964. conditions, replacements = zip(*caselist)
  4965. common_dtypes = [infer_dtype_from(arg)[0] for arg in [*replacements, default]]
  4966. if len(set(common_dtypes)) > 1:
  4967. common_dtype = find_common_type(common_dtypes)
  4968. updated_replacements = []
  4969. for condition, replacement in zip(conditions, replacements):
  4970. if is_scalar(replacement):
  4971. replacement = construct_1d_arraylike_from_scalar(
  4972. value=replacement, length=len(condition), dtype=common_dtype
  4973. )
  4974. elif isinstance(replacement, ABCSeries):
  4975. replacement = replacement.astype(common_dtype)
  4976. else:
  4977. replacement = pd_array(replacement, dtype=common_dtype)
  4978. updated_replacements.append(replacement)
  4979. replacements = updated_replacements
  4980. default = default.astype(common_dtype)
  4981. counter = reversed(range(len(conditions)))
  4982. for position, condition, replacement in zip(
  4983. counter, conditions[::-1], replacements[::-1]
  4984. ):
  4985. try:
  4986. default = default.mask(
  4987. condition, other=replacement, axis=0, inplace=False, level=None
  4988. )
  4989. except Exception as error:
  4990. raise ValueError(
  4991. f"Failed to apply condition{position} and replacement{position}."
  4992. ) from error
  4993. return default
  4994. # error: Cannot determine type of 'isna'
  4995. @doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  4996. def isna(self) -> Series:
  4997. return NDFrame.isna(self)
  4998. # error: Cannot determine type of 'isna'
  4999. @doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  5000. def isnull(self) -> Series:
  5001. """
  5002. Series.isnull is an alias for Series.isna.
  5003. """
  5004. return super().isnull()
  5005. # error: Cannot determine type of 'notna'
  5006. @doc(NDFrame.notna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  5007. def notna(self) -> Series:
  5008. return super().notna()
  5009. # error: Cannot determine type of 'notna'
  5010. @doc(NDFrame.notna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  5011. def notnull(self) -> Series:
  5012. """
  5013. Series.notnull is an alias for Series.notna.
  5014. """
  5015. return super().notnull()
  5016. @overload
  5017. def dropna(
  5018. self,
  5019. *,
  5020. axis: Axis = ...,
  5021. inplace: Literal[False] = ...,
  5022. how: AnyAll | None = ...,
  5023. ignore_index: bool = ...,
  5024. ) -> Series:
  5025. ...
  5026. @overload
  5027. def dropna(
  5028. self,
  5029. *,
  5030. axis: Axis = ...,
  5031. inplace: Literal[True],
  5032. how: AnyAll | None = ...,
  5033. ignore_index: bool = ...,
  5034. ) -> None:
  5035. ...
  5036. def dropna(
  5037. self,
  5038. *,
  5039. axis: Axis = 0,
  5040. inplace: bool = False,
  5041. how: AnyAll | None = None,
  5042. ignore_index: bool = False,
  5043. ) -> Series | None:
  5044. """
  5045. Return a new Series with missing values removed.
  5046. See the :ref:`User Guide <missing_data>` for more on which values are
  5047. considered missing, and how to work with missing data.
  5048. Parameters
  5049. ----------
  5050. axis : {0 or 'index'}
  5051. Unused. Parameter needed for compatibility with DataFrame.
  5052. inplace : bool, default False
  5053. If True, do operation inplace and return None.
  5054. how : str, optional
  5055. Not in use. Kept for compatibility.
  5056. ignore_index : bool, default ``False``
  5057. If ``True``, the resulting axis will be labeled 0, 1, …, n - 1.
  5058. .. versionadded:: 2.0.0
  5059. Returns
  5060. -------
  5061. Series or None
  5062. Series with NA entries dropped from it or None if ``inplace=True``.
  5063. See Also
  5064. --------
  5065. Series.isna: Indicate missing values.
  5066. Series.notna : Indicate existing (non-missing) values.
  5067. Series.fillna : Replace missing values.
  5068. DataFrame.dropna : Drop rows or columns which contain NA values.
  5069. Index.dropna : Drop missing indices.
  5070. Examples
  5071. --------
  5072. >>> ser = pd.Series([1., 2., np.nan])
  5073. >>> ser
  5074. 0 1.0
  5075. 1 2.0
  5076. 2 NaN
  5077. dtype: float64
  5078. Drop NA values from a Series.
  5079. >>> ser.dropna()
  5080. 0 1.0
  5081. 1 2.0
  5082. dtype: float64
  5083. Empty strings are not considered NA values. ``None`` is considered an
  5084. NA value.
  5085. >>> ser = pd.Series([np.nan, 2, pd.NaT, '', None, 'I stay'])
  5086. >>> ser
  5087. 0 NaN
  5088. 1 2
  5089. 2 NaT
  5090. 3
  5091. 4 None
  5092. 5 I stay
  5093. dtype: object
  5094. >>> ser.dropna()
  5095. 1 2
  5096. 3
  5097. 5 I stay
  5098. dtype: object
  5099. """
  5100. inplace = validate_bool_kwarg(inplace, "inplace")
  5101. ignore_index = validate_bool_kwarg(ignore_index, "ignore_index")
  5102. # Validate the axis parameter
  5103. self._get_axis_number(axis or 0)
  5104. if self._can_hold_na:
  5105. result = remove_na_arraylike(self)
  5106. else:
  5107. if not inplace:
  5108. result = self.copy(deep=None)
  5109. else:
  5110. result = self
  5111. if ignore_index:
  5112. result.index = default_index(len(result))
  5113. if inplace:
  5114. return self._update_inplace(result)
  5115. else:
  5116. return result
  5117. # ----------------------------------------------------------------------
  5118. # Time series-oriented methods
  5119. def to_timestamp(
  5120. self,
  5121. freq: Frequency | None = None,
  5122. how: Literal["s", "e", "start", "end"] = "start",
  5123. copy: bool | None = None,
  5124. ) -> Series:
  5125. """
  5126. Cast to DatetimeIndex of Timestamps, at *beginning* of period.
  5127. Parameters
  5128. ----------
  5129. freq : str, default frequency of PeriodIndex
  5130. Desired frequency.
  5131. how : {'s', 'e', 'start', 'end'}
  5132. Convention for converting period to timestamp; start of period
  5133. vs. end.
  5134. copy : bool, default True
  5135. Whether or not to return a copy.
  5136. .. note::
  5137. The `copy` keyword will change behavior in pandas 3.0.
  5138. `Copy-on-Write
  5139. <https://pandas.pydata.org/docs/dev/user_guide/copy_on_write.html>`__
  5140. will be enabled by default, which means that all methods with a
  5141. `copy` keyword will use a lazy copy mechanism to defer the copy and
  5142. ignore the `copy` keyword. The `copy` keyword will be removed in a
  5143. future version of pandas.
  5144. You can already get the future behavior and improvements through
  5145. enabling copy on write ``pd.options.mode.copy_on_write = True``
  5146. Returns
  5147. -------
  5148. Series with DatetimeIndex
  5149. Examples
  5150. --------
  5151. >>> idx = pd.PeriodIndex(['2023', '2024', '2025'], freq='Y')
  5152. >>> s1 = pd.Series([1, 2, 3], index=idx)
  5153. >>> s1
  5154. 2023 1
  5155. 2024 2
  5156. 2025 3
  5157. Freq: Y-DEC, dtype: int64
  5158. The resulting frequency of the Timestamps is `YearBegin`
  5159. >>> s1 = s1.to_timestamp()
  5160. >>> s1
  5161. 2023-01-01 1
  5162. 2024-01-01 2
  5163. 2025-01-01 3
  5164. Freq: YS-JAN, dtype: int64
  5165. Using `freq` which is the offset that the Timestamps will have
  5166. >>> s2 = pd.Series([1, 2, 3], index=idx)
  5167. >>> s2 = s2.to_timestamp(freq='M')
  5168. >>> s2
  5169. 2023-01-31 1
  5170. 2024-01-31 2
  5171. 2025-01-31 3
  5172. Freq: YE-JAN, dtype: int64
  5173. """
  5174. if not isinstance(self.index, PeriodIndex):
  5175. raise TypeError(f"unsupported Type {type(self.index).__name__}")
  5176. new_obj = self.copy(deep=copy and not using_copy_on_write())
  5177. new_index = self.index.to_timestamp(freq=freq, how=how)
  5178. setattr(new_obj, "index", new_index)
  5179. return new_obj
  5180. def to_period(self, freq: str | None = None, copy: bool | None = None) -> Series:
  5181. """
  5182. Convert Series from DatetimeIndex to PeriodIndex.
  5183. Parameters
  5184. ----------
  5185. freq : str, default None
  5186. Frequency associated with the PeriodIndex.
  5187. copy : bool, default True
  5188. Whether or not to return a copy.
  5189. .. note::
  5190. The `copy` keyword will change behavior in pandas 3.0.
  5191. `Copy-on-Write
  5192. <https://pandas.pydata.org/docs/dev/user_guide/copy_on_write.html>`__
  5193. will be enabled by default, which means that all methods with a
  5194. `copy` keyword will use a lazy copy mechanism to defer the copy and
  5195. ignore the `copy` keyword. The `copy` keyword will be removed in a
  5196. future version of pandas.
  5197. You can already get the future behavior and improvements through
  5198. enabling copy on write ``pd.options.mode.copy_on_write = True``
  5199. Returns
  5200. -------
  5201. Series
  5202. Series with index converted to PeriodIndex.
  5203. Examples
  5204. --------
  5205. >>> idx = pd.DatetimeIndex(['2023', '2024', '2025'])
  5206. >>> s = pd.Series([1, 2, 3], index=idx)
  5207. >>> s = s.to_period()
  5208. >>> s
  5209. 2023 1
  5210. 2024 2
  5211. 2025 3
  5212. Freq: Y-DEC, dtype: int64
  5213. Viewing the index
  5214. >>> s.index
  5215. PeriodIndex(['2023', '2024', '2025'], dtype='period[Y-DEC]')
  5216. """
  5217. if not isinstance(self.index, DatetimeIndex):
  5218. raise TypeError(f"unsupported Type {type(self.index).__name__}")
  5219. new_obj = self.copy(deep=copy and not using_copy_on_write())
  5220. new_index = self.index.to_period(freq=freq)
  5221. setattr(new_obj, "index", new_index)
  5222. return new_obj
  5223. # ----------------------------------------------------------------------
  5224. # Add index
  5225. _AXIS_ORDERS: list[Literal["index", "columns"]] = ["index"]
  5226. _AXIS_LEN = len(_AXIS_ORDERS)
  5227. _info_axis_number: Literal[0] = 0
  5228. _info_axis_name: Literal["index"] = "index"
  5229. index = properties.AxisProperty(
  5230. axis=0,
  5231. doc="""
  5232. The index (axis labels) of the Series.
  5233. The index of a Series is used to label and identify each element of the
  5234. underlying data. The index can be thought of as an immutable ordered set
  5235. (technically a multi-set, as it may contain duplicate labels), and is
  5236. used to index and align data in pandas.
  5237. Returns
  5238. -------
  5239. Index
  5240. The index labels of the Series.
  5241. See Also
  5242. --------
  5243. Series.reindex : Conform Series to new index.
  5244. Index : The base pandas index type.
  5245. Notes
  5246. -----
  5247. For more information on pandas indexing, see the `indexing user guide
  5248. <https://pandas.pydata.org/docs/user_guide/indexing.html>`__.
  5249. Examples
  5250. --------
  5251. To create a Series with a custom index and view the index labels:
  5252. >>> cities = ['Kolkata', 'Chicago', 'Toronto', 'Lisbon']
  5253. >>> populations = [14.85, 2.71, 2.93, 0.51]
  5254. >>> city_series = pd.Series(populations, index=cities)
  5255. >>> city_series.index
  5256. Index(['Kolkata', 'Chicago', 'Toronto', 'Lisbon'], dtype='object')
  5257. To change the index labels of an existing Series:
  5258. >>> city_series.index = ['KOL', 'CHI', 'TOR', 'LIS']
  5259. >>> city_series.index
  5260. Index(['KOL', 'CHI', 'TOR', 'LIS'], dtype='object')
  5261. """,
  5262. )
  5263. # ----------------------------------------------------------------------
  5264. # Accessor Methods
  5265. # ----------------------------------------------------------------------
  5266. str = CachedAccessor("str", StringMethods)
  5267. dt = CachedAccessor("dt", CombinedDatetimelikeProperties)
  5268. cat = CachedAccessor("cat", CategoricalAccessor)
  5269. plot = CachedAccessor("plot", pandas.plotting.PlotAccessor)
  5270. sparse = CachedAccessor("sparse", SparseAccessor)
  5271. struct = CachedAccessor("struct", StructAccessor)
  5272. list = CachedAccessor("list", ListAccessor)
  5273. # ----------------------------------------------------------------------
  5274. # Add plotting methods to Series
  5275. hist = pandas.plotting.hist_series
  5276. # ----------------------------------------------------------------------
  5277. # Template-Based Arithmetic/Comparison Methods
  5278. def _cmp_method(self, other, op):
  5279. res_name = ops.get_op_result_name(self, other)
  5280. if isinstance(other, Series) and not self._indexed_same(other):
  5281. raise ValueError("Can only compare identically-labeled Series objects")
  5282. lvalues = self._values
  5283. rvalues = extract_array(other, extract_numpy=True, extract_range=True)
  5284. res_values = ops.comparison_op(lvalues, rvalues, op)
  5285. return self._construct_result(res_values, name=res_name)
  5286. def _logical_method(self, other, op):
  5287. res_name = ops.get_op_result_name(self, other)
  5288. self, other = self._align_for_op(other, align_asobject=True)
  5289. lvalues = self._values
  5290. rvalues = extract_array(other, extract_numpy=True, extract_range=True)
  5291. res_values = ops.logical_op(lvalues, rvalues, op)
  5292. return self._construct_result(res_values, name=res_name)
  5293. def _arith_method(self, other, op):
  5294. self, other = self._align_for_op(other)
  5295. return base.IndexOpsMixin._arith_method(self, other, op)
  5296. def _align_for_op(self, right, align_asobject: bool = False):
  5297. """align lhs and rhs Series"""
  5298. # TODO: Different from DataFrame._align_for_op, list, tuple and ndarray
  5299. # are not coerced here
  5300. # because Series has inconsistencies described in GH#13637
  5301. left = self
  5302. if isinstance(right, Series):
  5303. # avoid repeated alignment
  5304. if not left.index.equals(right.index):
  5305. if align_asobject:
  5306. if left.dtype not in (object, np.bool_) or right.dtype not in (
  5307. object,
  5308. np.bool_,
  5309. ):
  5310. warnings.warn(
  5311. "Operation between Series with different indexes "
  5312. "that are not of numpy boolean or object dtype "
  5313. "will no longer return a numpy boolean result "
  5314. "in a future version. "
  5315. "Cast both Series to object type "
  5316. "to maintain the prior behavior.",
  5317. FutureWarning,
  5318. stacklevel=find_stack_level(),
  5319. )
  5320. # to keep original value's dtype for bool ops
  5321. left = left.astype(object)
  5322. right = right.astype(object)
  5323. left, right = left.align(right, copy=False)
  5324. return left, right
  5325. def _binop(self, other: Series, func, level=None, fill_value=None) -> Series:
  5326. """
  5327. Perform generic binary operation with optional fill value.
  5328. Parameters
  5329. ----------
  5330. other : Series
  5331. func : binary operator
  5332. fill_value : float or object
  5333. Value to substitute for NA/null values. If both Series are NA in a
  5334. location, the result will be NA regardless of the passed fill value.
  5335. level : int or level name, default None
  5336. Broadcast across a level, matching Index values on the
  5337. passed MultiIndex level.
  5338. Returns
  5339. -------
  5340. Series
  5341. """
  5342. this = self
  5343. if not self.index.equals(other.index):
  5344. this, other = self.align(other, level=level, join="outer", copy=False)
  5345. this_vals, other_vals = ops.fill_binop(this._values, other._values, fill_value)
  5346. with np.errstate(all="ignore"):
  5347. result = func(this_vals, other_vals)
  5348. name = ops.get_op_result_name(self, other)
  5349. out = this._construct_result(result, name)
  5350. return cast(Series, out)
  5351. def _construct_result(
  5352. self, result: ArrayLike | tuple[ArrayLike, ArrayLike], name: Hashable
  5353. ) -> Series | tuple[Series, Series]:
  5354. """
  5355. Construct an appropriately-labelled Series from the result of an op.
  5356. Parameters
  5357. ----------
  5358. result : ndarray or ExtensionArray
  5359. name : Label
  5360. Returns
  5361. -------
  5362. Series
  5363. In the case of __divmod__ or __rdivmod__, a 2-tuple of Series.
  5364. """
  5365. if isinstance(result, tuple):
  5366. # produced by divmod or rdivmod
  5367. res1 = self._construct_result(result[0], name=name)
  5368. res2 = self._construct_result(result[1], name=name)
  5369. # GH#33427 assertions to keep mypy happy
  5370. assert isinstance(res1, Series)
  5371. assert isinstance(res2, Series)
  5372. return (res1, res2)
  5373. # TODO: result should always be ArrayLike, but this fails for some
  5374. # JSONArray tests
  5375. dtype = getattr(result, "dtype", None)
  5376. out = self._constructor(result, index=self.index, dtype=dtype, copy=False)
  5377. out = out.__finalize__(self)
  5378. # Set the result's name after __finalize__ is called because __finalize__
  5379. # would set it back to self.name
  5380. out.name = name
  5381. return out
  5382. def _flex_method(self, other, op, *, level=None, fill_value=None, axis: Axis = 0):
  5383. if axis is not None:
  5384. self._get_axis_number(axis)
  5385. res_name = ops.get_op_result_name(self, other)
  5386. if isinstance(other, Series):
  5387. return self._binop(other, op, level=level, fill_value=fill_value)
  5388. elif isinstance(other, (np.ndarray, list, tuple)):
  5389. if len(other) != len(self):
  5390. raise ValueError("Lengths must be equal")
  5391. other = self._constructor(other, self.index, copy=False)
  5392. result = self._binop(other, op, level=level, fill_value=fill_value)
  5393. result._name = res_name
  5394. return result
  5395. else:
  5396. if fill_value is not None:
  5397. if isna(other):
  5398. return op(self, fill_value)
  5399. self = self.fillna(fill_value)
  5400. return op(self, other)
  5401. @Appender(ops.make_flex_doc("eq", "series"))
  5402. def eq(
  5403. self,
  5404. other,
  5405. level: Level | None = None,
  5406. fill_value: float | None = None,
  5407. axis: Axis = 0,
  5408. ) -> Series:
  5409. return self._flex_method(
  5410. other, operator.eq, level=level, fill_value=fill_value, axis=axis
  5411. )
  5412. @Appender(ops.make_flex_doc("ne", "series"))
  5413. def ne(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5414. return self._flex_method(
  5415. other, operator.ne, level=level, fill_value=fill_value, axis=axis
  5416. )
  5417. @Appender(ops.make_flex_doc("le", "series"))
  5418. def le(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5419. return self._flex_method(
  5420. other, operator.le, level=level, fill_value=fill_value, axis=axis
  5421. )
  5422. @Appender(ops.make_flex_doc("lt", "series"))
  5423. def lt(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5424. return self._flex_method(
  5425. other, operator.lt, level=level, fill_value=fill_value, axis=axis
  5426. )
  5427. @Appender(ops.make_flex_doc("ge", "series"))
  5428. def ge(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5429. return self._flex_method(
  5430. other, operator.ge, level=level, fill_value=fill_value, axis=axis
  5431. )
  5432. @Appender(ops.make_flex_doc("gt", "series"))
  5433. def gt(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5434. return self._flex_method(
  5435. other, operator.gt, level=level, fill_value=fill_value, axis=axis
  5436. )
  5437. @Appender(ops.make_flex_doc("add", "series"))
  5438. def add(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5439. return self._flex_method(
  5440. other, operator.add, level=level, fill_value=fill_value, axis=axis
  5441. )
  5442. @Appender(ops.make_flex_doc("radd", "series"))
  5443. def radd(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5444. return self._flex_method(
  5445. other, roperator.radd, level=level, fill_value=fill_value, axis=axis
  5446. )
  5447. @Appender(ops.make_flex_doc("sub", "series"))
  5448. def sub(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5449. return self._flex_method(
  5450. other, operator.sub, level=level, fill_value=fill_value, axis=axis
  5451. )
  5452. subtract = sub
  5453. @Appender(ops.make_flex_doc("rsub", "series"))
  5454. def rsub(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5455. return self._flex_method(
  5456. other, roperator.rsub, level=level, fill_value=fill_value, axis=axis
  5457. )
  5458. @Appender(ops.make_flex_doc("mul", "series"))
  5459. def mul(
  5460. self,
  5461. other,
  5462. level: Level | None = None,
  5463. fill_value: float | None = None,
  5464. axis: Axis = 0,
  5465. ) -> Series:
  5466. return self._flex_method(
  5467. other, operator.mul, level=level, fill_value=fill_value, axis=axis
  5468. )
  5469. multiply = mul
  5470. @Appender(ops.make_flex_doc("rmul", "series"))
  5471. def rmul(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5472. return self._flex_method(
  5473. other, roperator.rmul, level=level, fill_value=fill_value, axis=axis
  5474. )
  5475. @Appender(ops.make_flex_doc("truediv", "series"))
  5476. def truediv(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5477. return self._flex_method(
  5478. other, operator.truediv, level=level, fill_value=fill_value, axis=axis
  5479. )
  5480. div = truediv
  5481. divide = truediv
  5482. @Appender(ops.make_flex_doc("rtruediv", "series"))
  5483. def rtruediv(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5484. return self._flex_method(
  5485. other, roperator.rtruediv, level=level, fill_value=fill_value, axis=axis
  5486. )
  5487. rdiv = rtruediv
  5488. @Appender(ops.make_flex_doc("floordiv", "series"))
  5489. def floordiv(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5490. return self._flex_method(
  5491. other, operator.floordiv, level=level, fill_value=fill_value, axis=axis
  5492. )
  5493. @Appender(ops.make_flex_doc("rfloordiv", "series"))
  5494. def rfloordiv(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5495. return self._flex_method(
  5496. other, roperator.rfloordiv, level=level, fill_value=fill_value, axis=axis
  5497. )
  5498. @Appender(ops.make_flex_doc("mod", "series"))
  5499. def mod(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5500. return self._flex_method(
  5501. other, operator.mod, level=level, fill_value=fill_value, axis=axis
  5502. )
  5503. @Appender(ops.make_flex_doc("rmod", "series"))
  5504. def rmod(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5505. return self._flex_method(
  5506. other, roperator.rmod, level=level, fill_value=fill_value, axis=axis
  5507. )
  5508. @Appender(ops.make_flex_doc("pow", "series"))
  5509. def pow(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5510. return self._flex_method(
  5511. other, operator.pow, level=level, fill_value=fill_value, axis=axis
  5512. )
  5513. @Appender(ops.make_flex_doc("rpow", "series"))
  5514. def rpow(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5515. return self._flex_method(
  5516. other, roperator.rpow, level=level, fill_value=fill_value, axis=axis
  5517. )
  5518. @Appender(ops.make_flex_doc("divmod", "series"))
  5519. def divmod(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5520. return self._flex_method(
  5521. other, divmod, level=level, fill_value=fill_value, axis=axis
  5522. )
  5523. @Appender(ops.make_flex_doc("rdivmod", "series"))
  5524. def rdivmod(self, other, level=None, fill_value=None, axis: Axis = 0) -> Series:
  5525. return self._flex_method(
  5526. other, roperator.rdivmod, level=level, fill_value=fill_value, axis=axis
  5527. )
  5528. # ----------------------------------------------------------------------
  5529. # Reductions
  5530. def _reduce(
  5531. self,
  5532. op,
  5533. # error: Variable "pandas.core.series.Series.str" is not valid as a type
  5534. name: str, # type: ignore[valid-type]
  5535. *,
  5536. axis: Axis = 0,
  5537. skipna: bool = True,
  5538. numeric_only: bool = False,
  5539. filter_type=None,
  5540. **kwds,
  5541. ):
  5542. """
  5543. Perform a reduction operation.
  5544. If we have an ndarray as a value, then simply perform the operation,
  5545. otherwise delegate to the object.
  5546. """
  5547. delegate = self._values
  5548. if axis is not None:
  5549. self._get_axis_number(axis)
  5550. if isinstance(delegate, ExtensionArray):
  5551. # dispatch to ExtensionArray interface
  5552. return delegate._reduce(name, skipna=skipna, **kwds)
  5553. else:
  5554. # dispatch to numpy arrays
  5555. if numeric_only and self.dtype.kind not in "iufcb":
  5556. # i.e. not is_numeric_dtype(self.dtype)
  5557. kwd_name = "numeric_only"
  5558. if name in ["any", "all"]:
  5559. kwd_name = "bool_only"
  5560. # GH#47500 - change to TypeError to match other methods
  5561. raise TypeError(
  5562. f"Series.{name} does not allow {kwd_name}={numeric_only} "
  5563. "with non-numeric dtypes."
  5564. )
  5565. return op(delegate, skipna=skipna, **kwds)
  5566. @Appender(make_doc("any", ndim=1))
  5567. # error: Signature of "any" incompatible with supertype "NDFrame"
  5568. def any( # type: ignore[override]
  5569. self,
  5570. *,
  5571. axis: Axis = 0,
  5572. bool_only: bool = False,
  5573. skipna: bool = True,
  5574. **kwargs,
  5575. ) -> bool:
  5576. nv.validate_logical_func((), kwargs, fname="any")
  5577. validate_bool_kwarg(skipna, "skipna", none_allowed=False)
  5578. return self._reduce(
  5579. nanops.nanany,
  5580. name="any",
  5581. axis=axis,
  5582. numeric_only=bool_only,
  5583. skipna=skipna,
  5584. filter_type="bool",
  5585. )
  5586. @Appender(make_doc("all", ndim=1))
  5587. def all(
  5588. self,
  5589. axis: Axis = 0,
  5590. bool_only: bool = False,
  5591. skipna: bool = True,
  5592. **kwargs,
  5593. ) -> bool:
  5594. nv.validate_logical_func((), kwargs, fname="all")
  5595. validate_bool_kwarg(skipna, "skipna", none_allowed=False)
  5596. return self._reduce(
  5597. nanops.nanall,
  5598. name="all",
  5599. axis=axis,
  5600. numeric_only=bool_only,
  5601. skipna=skipna,
  5602. filter_type="bool",
  5603. )
  5604. @doc(make_doc("min", ndim=1))
  5605. def min(
  5606. self,
  5607. axis: Axis | None = 0,
  5608. skipna: bool = True,
  5609. numeric_only: bool = False,
  5610. **kwargs,
  5611. ):
  5612. return NDFrame.min(self, axis, skipna, numeric_only, **kwargs)
  5613. @doc(make_doc("max", ndim=1))
  5614. def max(
  5615. self,
  5616. axis: Axis | None = 0,
  5617. skipna: bool = True,
  5618. numeric_only: bool = False,
  5619. **kwargs,
  5620. ):
  5621. return NDFrame.max(self, axis, skipna, numeric_only, **kwargs)
  5622. @doc(make_doc("sum", ndim=1))
  5623. def sum(
  5624. self,
  5625. axis: Axis | None = None,
  5626. skipna: bool = True,
  5627. numeric_only: bool = False,
  5628. min_count: int = 0,
  5629. **kwargs,
  5630. ):
  5631. return NDFrame.sum(self, axis, skipna, numeric_only, min_count, **kwargs)
  5632. @doc(make_doc("prod", ndim=1))
  5633. def prod(
  5634. self,
  5635. axis: Axis | None = None,
  5636. skipna: bool = True,
  5637. numeric_only: bool = False,
  5638. min_count: int = 0,
  5639. **kwargs,
  5640. ):
  5641. return NDFrame.prod(self, axis, skipna, numeric_only, min_count, **kwargs)
  5642. @doc(make_doc("mean", ndim=1))
  5643. def mean(
  5644. self,
  5645. axis: Axis | None = 0,
  5646. skipna: bool = True,
  5647. numeric_only: bool = False,
  5648. **kwargs,
  5649. ):
  5650. return NDFrame.mean(self, axis, skipna, numeric_only, **kwargs)
  5651. @doc(make_doc("median", ndim=1))
  5652. def median(
  5653. self,
  5654. axis: Axis | None = 0,
  5655. skipna: bool = True,
  5656. numeric_only: bool = False,
  5657. **kwargs,
  5658. ):
  5659. return NDFrame.median(self, axis, skipna, numeric_only, **kwargs)
  5660. @doc(make_doc("sem", ndim=1))
  5661. def sem(
  5662. self,
  5663. axis: Axis | None = None,
  5664. skipna: bool = True,
  5665. ddof: int = 1,
  5666. numeric_only: bool = False,
  5667. **kwargs,
  5668. ):
  5669. return NDFrame.sem(self, axis, skipna, ddof, numeric_only, **kwargs)
  5670. @doc(make_doc("var", ndim=1))
  5671. def var(
  5672. self,
  5673. axis: Axis | None = None,
  5674. skipna: bool = True,
  5675. ddof: int = 1,
  5676. numeric_only: bool = False,
  5677. **kwargs,
  5678. ):
  5679. return NDFrame.var(self, axis, skipna, ddof, numeric_only, **kwargs)
  5680. @doc(make_doc("std", ndim=1))
  5681. def std(
  5682. self,
  5683. axis: Axis | None = None,
  5684. skipna: bool = True,
  5685. ddof: int = 1,
  5686. numeric_only: bool = False,
  5687. **kwargs,
  5688. ):
  5689. return NDFrame.std(self, axis, skipna, ddof, numeric_only, **kwargs)
  5690. @doc(make_doc("skew", ndim=1))
  5691. def skew(
  5692. self,
  5693. axis: Axis | None = 0,
  5694. skipna: bool = True,
  5695. numeric_only: bool = False,
  5696. **kwargs,
  5697. ):
  5698. return NDFrame.skew(self, axis, skipna, numeric_only, **kwargs)
  5699. @doc(make_doc("kurt", ndim=1))
  5700. def kurt(
  5701. self,
  5702. axis: Axis | None = 0,
  5703. skipna: bool = True,
  5704. numeric_only: bool = False,
  5705. **kwargs,
  5706. ):
  5707. return NDFrame.kurt(self, axis, skipna, numeric_only, **kwargs)
  5708. kurtosis = kurt
  5709. product = prod
  5710. @doc(make_doc("cummin", ndim=1))
  5711. def cummin(self, axis: Axis | None = None, skipna: bool = True, *args, **kwargs):
  5712. return NDFrame.cummin(self, axis, skipna, *args, **kwargs)
  5713. @doc(make_doc("cummax", ndim=1))
  5714. def cummax(self, axis: Axis | None = None, skipna: bool = True, *args, **kwargs):
  5715. return NDFrame.cummax(self, axis, skipna, *args, **kwargs)
  5716. @doc(make_doc("cumsum", ndim=1))
  5717. def cumsum(self, axis: Axis | None = None, skipna: bool = True, *args, **kwargs):
  5718. return NDFrame.cumsum(self, axis, skipna, *args, **kwargs)
  5719. @doc(make_doc("cumprod", 1))
  5720. def cumprod(self, axis: Axis | None = None, skipna: bool = True, *args, **kwargs):
  5721. return NDFrame.cumprod(self, axis, skipna, *args, **kwargs)