Package: a-pandas-ex-less-memory-more-speed
Less memory usage - more speedA Python package to reduce the memory usage of pandas DataFrames without changing the underlying data. It speeds up your workflow and reduces the risk of running out of memory.Installationpipinstalla-pandas-ex-less-memory-more-speedfroma_pandas_ex_less_memory_more_speedimportpd_add_less_memory_more_speedpd_add_less_memory_more_speed()importpandasaspddf=pd.read_csv("https://github.com/pandas-dev/pandas/raw/main/doc/data/titanic.csv",)df.ds_reduce_memory_size()Update 2023/05/04# to carefully handle callables, iterables and other objects in cellsdf.ds_reduce_memory_size_carefully()OptimizesthememoryusageofapandasDataFrameorSeriesbyconvertingdatatypesandreducingmemorysize.Args:df_(pd.Series|pd.DataFrame):TheDataFrameorSeriestobeoptimized.ignore_columns(tuple|list,optional):Atupleorlistofcolumnnamestoignoreduringoptimization.Defaultsto().not_allowed_to_convert(tuple|list,optional):Atupleorlistofmodulesthatshouldnotbeconvertedduringoptimization.Defaultsto("shapely",).allowed_to_convert(tuple|list,optional):Atupleorlistofmodulesthatareallowedtobeconvertedduringoptimization.Defaultsto("pandas","numpy").include_empty_iters_in_pd_na(bool,optional):IfTrue,emptyiteratorswillbeconvertedtopd.NAduringoptimization.DefaultstoFalse.include_0_len_string_in_pd_na(bool,optional):IfTrue,zero-lengthstringswillbeconvertedtopd.NAduringoptimization.DefaultstoFalse.verbose(bool,optional):IfTrue,printinformationaboutthememoryusagebeforeandafteroptimization.DefaultstoTrue.Returns:pd.DataFrame|pd.Series:TheoptimizedDataFrameorSeries.Raises:None.Update 2022/10/08#added pandas.Series.ds_optimize_int / pandas.DataFrame.ds_optimize_int#to optimize only intsPassengerIdSurvivedPclass...FareCabinEmbarked0103...7.2500NaNS1211...71.2833C85C2313...7.9250NaNS3411...53.1000C123S4503...8.0500NaNS.......................88688702...13.0000NaNS88788811...30.0000B42S88888903...23.4500NaNS88989011...30.0000C148C89089103...7.7500NaNQ[891rowsx12columns]df.ds_optimize_int()df.PassengerId:Usingdtype:np.uint16df.Survived:Usingdtype:np.uint8df.Pclass:Usingdtype:np.uint8df.SibSp:Usingdtype:np.uint8df.Parch:Usingdtype:np.uint8Out[7]:PassengerIdSurvivedPclass...FareCabinEmbarked0103...7.2500NaNS1211...71.2833C85C2313...7.9250NaNS3411...53.1000C123S4503...8.0500NaNS.......................88688702...13.0000NaNS88788811...30.0000B42S88888903...23.4500NaNS88989011...30.0000C148C89089103...7.7500NaNQUsagedf=pd.read_csv("https://github.com/pandas-dev/pandas/raw/main/doc/data/titanic.csv",)fromrandomimportchoice#Let's add some more data typestruefalse=lambda:choice([True,False])df['truefalse']=[truefalse()forxinrange(len(df))]df['onlynan']=pd.NAdf['nestedlists']=[[[1]*10]]*len(df)mixedstuff=lambda:choice([True,False,'right','wrong',1,2,23,343.555,23.444,[442,553,44],[],''])df['mixedstuff']=[mixedstuff()forxinrange(len(df))]floatnumbers=lambda:choice([33.44,344.42424265,15.0,3222.33])df['floatnumbers']=[floatnumbers()forxinrange(len(df))]floatnumbers0=lambda:choice([33.0,344.0,15.0,3222.0])df['floatnumbers0']=[floatnumbers0()forxinrange(len(df))]intwithnan=lambda:choice([1,2,3,4,5,pd.NA])df['intwithnan']=[intwithnan()forxinrange(len(df))]df2=optimize_dtypes(dframe=df,point_zero_to_int=True,categorylimit=15,verbose=True,include_na_strings_in_pd_na=True,include_empty_iters_in_pd_na=True,include_0_len_string_in_pd_na=True,convert_float=True,check_float_difference=True,float_tolerance_negative=-0.1,float_tolerance_positive=0.1,)print(df)print(df2)print(df.dtypes)print(df2.dtypes)Memoryusageofdataframeis:0.12333202362060547MBâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.PassengerId----------------df.PassengerIdIsnumeric!df.PassengerIdMax:891df.PassengerIdMin:1df.PassengerId:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.PassengerId:Usingdtype:np.uint16â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Survived----------------df.SurvivedIsnumeric!df.SurvivedMax:1df.SurvivedMin:0df.Survived:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.Survived:Usingdtype:np.uint8â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Pclass----------------df.PclassIsnumeric!df.PclassMax:3df.PclassMin:1df.Pclass:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.Pclass:Usingdtype:np.uint8â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Name----------------df.Name:Usingdtype:stringâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Sex----------------df.Sex:Usingdtype:categoryâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Age----------------df.AgeIsnumeric!df.AgeMax:80.0df.AgeMin:0.42df.Age:Usingdtype:Float64â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.SibSp----------------df.SibSpIsnumeric!df.SibSpMax:8df.SibSpMin:0df.SibSp:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.SibSp:Usingdtype:np.uint8â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Parch----------------df.ParchIsnumeric!df.ParchMax:6df.ParchMin:0df.Parch:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.Parch:Usingdtype:np.uint8â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Ticket----------------df.Ticket:Usingdtype:stringâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Fare----------------df.FareIsnumeric!df.FareMax:512.3292df.FareMin:0.0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMax.positivedifference-limit0.1498-0.05305-0.05708-0.05Max.negativedifference-limit-0.16790.17082580.17087370.1708xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-------------<class'numpy.float16'> ------------- not right for df.FareCheckingnextdtype...True->withinthedesiredrange:0.1/-0.1False5True886-------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMax.positivedifference-limit0.100.05870.05880.0Max.negativedifference-limit-0.100.05980.05870.0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx+++++++++++++<class'numpy.float32'> +++++++++++++ right for df.FareTrue->withinthedesiredrange:0.1/-0.1True891-------------------df.Fare:Usingdtype:np.float32â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Cabin----------------df.Cabin:Usingdtype:stringâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.Embarked----------------df.Embarked:Usingdtype:categoryâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.truefalse----------------df.truefalse:Usingdtype:np.bool_â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.onlynan----------------df.onlynanIsnumeric!df.onlynanMax:nandf.onlynanMin:nandf.onlynan:Onlynanincolumn,continue...â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.nestedlists----------------â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.mixedstuff----------------â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.floatnumbers----------------df.floatnumbersIsnumeric!df.floatnumbersMax:3222.33df.floatnumbersMin:15.0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMax.positivedifference-limit0.1890-0.33597-0.33592-0.33Max.negativedifference-limit-0.15270.0757571900.0757571710.075757xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-------------<class'numpy.float16'> ------------- not right for df.floatnumbersCheckingnextdtype...True->withinthedesiredrange:0.1/-0.1False219True672-------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMax.positivedifference-limit0.100.05870.05880.0Max.negativedifference-limit-0.100.05980.05870.0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx+++++++++++++<class'numpy.float32'> +++++++++++++ right for df.floatnumbersTrue->withinthedesiredrange:0.1/-0.1True891-------------------df.floatnumbers:Usingdtype:np.float32â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.floatnumbers0----------------df.floatnumbers0Isnumeric!df.floatnumbers0Max:3222.0df.floatnumbers0Min:15.0df.floatnumbers0:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.floatnumbers0:Usingdtype:np.uint16â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆAnalyzingdf.intwithnan----------------df.intwithnanIsnumeric!df.intwithnanMax:5df.intwithnanMin:1df.intwithnan:Only.000incolumns->Usingint-Checkingwhichsizefitsbest...df.intwithnan:Usingdtype:Int64â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆMemoryusageofdataframewas:0.12333202362060547MBMemoryusageofdataframeisnow:0.07259273529052734MBThisis58.85959960718511%oftheinitialsizeâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆPassengerIdSurvivedPclass...floatnumbersfloatnumbers0intwithnan0103...33.44000033.041211...3222.33000015.052313...33.44000033.033411...15.00000033.014503...15.000000344.02.......................88688702...344.424243344.0588788811...15.00000015.0488888903...344.4242433222.0288989011...344.4242433222.0489089103...3222.3300003222.0<NA>[891rowsx19columns]PassengerIdSurvivedPclass...floatnumbersfloatnumbers0intwithnan0103...33.4399993341211...3222.3300781552313...33.4399993333411...15.0000003314503...15.0000003442.......................88688702...344.424255344588788811...15.00000015488888903...344.4242553222288989011...344.4242553222489089103...3222.3300783222<NA>[891rowsx19columns]PassengerIdint64Survivedint64Pclassint64NameobjectSexobjectAgefloat64SibSpint64Parchint64TicketobjectFarefloat64CabinobjectEmbarkedobjecttruefalseboolonlynanobjectnestedlistsobjectmixedstuffobjectfloatnumbersfloat64floatnumbers0float64intwithnanobjectdtype:objectPassengerIduint16Surviveduint8Pclassuint8NamestringSexcategoryAgeFloat64SibSpuint8Parchuint8TicketstringFarefloat32CabinstringEmbarkedcategorytruefalseboolonlynanobjectnestedlistsobjectmixedstuffobjectfloatnumbersfloat32floatnumbers0uint16intwithnanInt64dtype:objectParameters:dframe:Union[pd.Series,pd.DataFrame]pd.Series,pd.DataFramepoint_zero_to_int:boolConvertfloattointifallfloatnumbersinthecolumnendwith.0+(default=True)categorylimit:intConvertstringstocategory,whenratiolen(df)/len(df.value_counts)>=categorylimit(default=4)verbose:boolKeeptrackofwhatishappening(default=True)include_na_strings_in_pd_na:boolWhenTrue->treatedasnan:["<NA>","<NAN>","<nan>","np.nan","NoneType","None","-1.#IND","1.#QNAN","1.#IND","-1.#QNAN","#N/A N/A","#N/A","N/A","n/a","NA","#NA","NULL","null","NaN","-NaN","nan","-nan",](default=True)include_empty_iters_in_pd_na:boolWhenTrue->[],{}aretreatedasnan(default=False)include_0_len_string_in_pd_na:boolWhenTrue->''istreatedasnan(default=False)convert_float:boolDon't convert columns containing float numbers.Comparingthe2dataframesfromtheexample,onecanseethatfloatnumbersfrequentlydon't have the exact same value as the original float number.Ifdecimaldigitsareimportantforyourwork,disableit!(default=True)check_float_difference:boolIfalittledifferencebetweenfloatdtypesisfineforyou,useTrueIgnoredifconvert_float=False(default=True)float_tolerance_negative:floatThenegativetoleranceyoucanlivewith,e.g.3222.330078-3222.330000=0.000078isfineforyouIgnoredifconvert_float=False(default=0)float_tolerance_positive:float=0,Thepositivetoleranceyoucanlivewith3222.340078-3222.330000=0.010078isfineforyouIgnoredifconvert_float=False(default=0.05)Returns:Union[pd.DataFrame,pd.Series]