Package: py-paretoarchive
Archive of non-dominated pointsCreating an archive of all non-dominated points using Fast Incremental BSP Tree. This package provides a Python wrapper for code provided asa fast incremental BSP archive.COMPILATIONpython3-mpipinstall--userpy-paretoarchiveThe package requires Cython module for its run. On Windows, you will need to haveMicrosoft Build Tools. Note that PyPi suggest you a link to the proper tool after this command.Instalation from sourcespip3installpytestCython
makeinstall-from-source
pytestThe package requires Cython module for its run. When Cython is correctly installed, the package should be platform independent.USAGEPyBspTreeArchive(objectives=3,minimizeObjective1=True,minimizeObjective2=True,minimizeObjective3=True,minimizeObjective4=True)fromparetoarchiveimportPyBspTreeArchivea=PyBspTreeArchive(3,minimizeObjective1=False,minimizeObjective2=False,minimizeObjective3=True)a.process([1,2,3])# True (is non-dominated)a.process([1,2,3])# True (is non-dominated)a.process([1,3,3])# True (is non-dominated)a.process([1,1,2])# True (is non-dominated)print(a.size())# get the number of  non-dominates solutions# 2print(a.points())# get the non-dominated solutions# [[1.0, 3.0, 3.0], [1.0, 1.0, 2.0]]Single-line example:print(PyBspTreeArchive(2,minimizeObjective1=True,minimizeObjective2=False).filter([[2,4],[3,1],[2,1],[1,1]],sortKey=lambdaitm:itm[0])#process the array and sort the result by first objective (useful for plotting)# [[1.0, 1.0], [2.0, 4.0]]Return indexes of the elements:a=PyBspTreeArchive(3,minimizeObjective1=True,minimizeObjective2=False)print(a.process([1,3,3],returnId=True))# (True, 0) (is non-dominated, received ID 0)print(a.process([1,2,3],returnId=True))# (False, 1) (is dominated, received ID 1)print(a.process([1,1,2],returnId=True))# (True, 2) (is non-dominated, received ID 2)print(a.points(returnIds=True))# [0,2] (item with ID 0 and 2 are non-dominated)print(a.points())# [[1.0, 3.0, 3.0], [1.0, 1.0, 2.0]]Custom IDs:a=PyBspTreeArchive(3,minimizeObjective1=True,minimizeObjective2=False)print(a.process([1,2,3],customId=10))# Trueprint(a.process([1,3,3],customId=20))# Trueprint(a.process([1,1,2],customId=30))# Trueprint(a.points(returnIds=True))# [20,30]Pruning of the set of non-dominated solutions specifying data resolution:defresample(val,resolution=0.01):returnround(val/resolution)*resolutionpf=PyBspTreeArchive(4)fori,xinenumerate(dataset):pf.process((resample(math.log10(x['wce']),0.001),#resolution is 0.001resample(x['area'],10),#values can be only multiples of 10resample(x['pwr'],0.1),#resolution is 0.1resample(x['time'],0.1)#resolution is 0.1),customId=i)#customId may be omitted, there is an internal counter initialized to 0indexes=pf.points(returnIds=True)print([dataset[i]['wce']foriinindexes])Using in PandasYou can easily use the library to filter a Pandas DataFrame. Note that the selected columns cannot have a "NaN" values (you should usedf.dropna(subset=["c1", "c2"])function.fromparetoarchive.pandasimportparetopar_df=pareto(df,["area","energy","weight"],minimizeObjective2=False)orfromparetoarchiveimportPyBspTreeArchivedefpandas_pareto(data:pd.DataFrame,columns:list,**kwargs)->pd.DataFrame:filt=list(zip(*[data[c]forcincolumns]))ids=data.index.tolist()sel=[ids[i]foriinPyBspTreeArchive(len(columns),**kwargs).filter(filt,returnIds=True)]filt=[iinselforiinids]returndata[filt]# example usagepar_df=pandas_pareto(df,["area","energy","weight"],minimizeObjective2=False)NotesThe values are internally repesented asdoublenumbers. For very large integers you may lose the precision.Up to 15 objectives can be handled.SOURCETobias Glasmachers:A Fast Incremental BSP Tree Archive for Non-dominated Pointshttps://link.springer.com/chapter/10.1007/978-3-319-54157-0_18https://www.ini.rub.de/PEOPLE/glasmtbl/code/ParetoArchive/index.htmlSimilar problem (SKYLINE)https://github.com/sean-chester/SkyBench