Package: cythonnestednumpy
performs sorting and grouping operations on multidimensional NumPy arrays using Cython and hash-based algorithms.pip install cythonnestednumpyTested against Windows / Python 3.11 / AnacondaCython (and a C/C++ compiler) must be installedimportnumpyasnpfromcythonnestednumpyimportHashSortimg1=np.full([900,1800,3],255,dtype=np.uint8)img2=np.full([900,1800,3],255,dtype=np.uint8)img2[...,0]=0img3=np.full([900,1800,3],255,dtype=np.uint8)img3[...,2]=1a=np.concatenate([img1,img2,img3])cyne=HashSort(a,unordered=True)# 1st column: absolut index (using a.flatten() or a.ravel())# 2nd - n column: dimension (the more dimensions your array has, the more columns will show up)# 3rd column: The index in cyne.iterray# 4th column: 1 is for the first item (unique) found. 0 means that there has been found the same value before.# 5th column: How many matches# 6th column: Hashcodecyne.generate_hash_array(last_dim=None)resultdata=cyne.sort_by_absolut_index(ascending=True)# Out[3]:# array([[                   0,                    0,                    1,                    1,  2497830064280488930],#        [                  30,                    1,                    0,                    2,  2497830064280488930],#        [                  60,                    2,                    0,                    3,  2497830064280488930],#        [                  90,                    3,                    0,                    4,  2497830064280488930],# ...#        [                 780,                   26,                    0,                    7, -5024405870974420794],#        [                 810,                   27,                    0,                    8, -5024405870974420794],#        [                 840,                   28,                    0,                    9, -5024405870974420794],#        [                 870,                   29,                    0,                   10, -5024405870974420794]], dtype=int64)cyne.sort_by_absolut_index(ascending=False)# Out[4]:# array([[                 870,                   29,                    0,                   10, -5024405870974420794],#        [                 840,                   28,                    0,                    9, -5024405870974420794],#        [                 810,                   27,                    0,                    8, -5024405870974420794],#        [                 780,                   26,                    0,                    7, -5024405870974420794],#        [                 750,                   25,                    0,                    6, -5024405870974420794],#        [                 720,                   24,                    0,                    5, -5024405870974420794],# ...#        [                 240,                    8,                    0,                    9,  2497830064280488930],#        [                 210,                    7,                    0,                    8,  2497830064280488930],#        [                 180,                    6,                    0,                    7,  2497830064280488930],#        [                 150,                    5,                    0,                    6,  2497830064280488930],#        [                 120,                    4,                    0,                    5,  2497830064280488930],#        [                  90,                    3,                    0,                    4,  2497830064280488930],#        [                  60,                    2,                    0,                    3,  2497830064280488930],#        [                  30,                    1,                    0,                    2,  2497830064280488930],#        [                   0,                    0,                    1,                    1,  2497830064280488930]], dtype=int64)cyne.get_unique_dims_data()# Out[3]:# [array([255, 255, 255], dtype=uint8),#  array([255, 255, 255], dtype=uint8),#  array([255, 255, 255], dtype=uint8)]cyne.get_unique_dims_data(start_dim=2,end_dim=-1)#          [255, 255, 255],#          [255, 255, 255],#          [255, 255, 255],#          [255, 255, 255],#          [255, 255, 255]],##         [[255, 255, 255],#          [255, 255, 255],#           ...#          [  0, 255, 255]],##         [[  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255],#          [  0, 255, 255]],cyne.get_all_values(start_dim=0,end_dim=-1)#         ...,#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255]],#        ...,#        [[255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [255, 255,   1]],#          ...,#allva=cyne.get_unique_dims_values()cyne.group_equal_values()#         [255, 255,   1]],#        [[255, 255,   1],#         [255, 255,   1],#         [255, 255,   1],#         [  0, 255, 255],#         [  0, 255, 255],#         ...#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255],#         [255, 255, 255]],groupedvalues=cyne.group_equal_values()byqty=cyne.sort_by_quantity(ascending=False)cyne.sort_by_hash(ascending=False)# Out[3]:# array([[                 270,                    9,                    0,                   10,  2497830064280488930],#        [                 240,                    8,                    0,                    9,  2497830064280488930],#        [                 210,                    7,                    0,                    8,  2497830064280488930],#        [                 180,                    6,                    0,                    7,  2497830064280488930],# ...#        [                 750,                   25,                    0,                    6, -5024405870974420794],#        [                 720,                   24,                    0,                    5, -5024405870974420794],#        [                 690,                   23,                    0,                    4, -5024405870974420794],#        [                 660,                   22,                    0,                    3, -5024405870974420794],#        [                 630,                   21,                    0,                    2, -5024405870974420794],#        [                 600,                   20,                    1,                    1, -5024405870974420794]], dtype=int64)classHashSort(builtins.object)|HashSort(a,unordered=True)||TheHashSortclassisdesignedtoperformsortingandgroupingoperationsonmulti-dimensionalNumPyarrays|usingahash-basedalgorithm.Itutilizesthexxhashhttps://xxhash.com/function(Cython!NotPython!)forefficienthashcomputation.||Parameters:|-a(numpy.ndarray):Theinputmulti-dimensionalNumPyarray.|-unordered(bool):IfTrue,willcreatetheindexarraywithmultiprocessing||Methods:|-generate_hash_array(last_dim=None):Generatesahasharraybasedontheprovidedarrayandoptionallast_dim.|-sort_by_absolut_index(ascending=True):Sortsthehasharraybyabsoluteindexinascendingordescendingorder.|-get_unique_dims_data(start_dim=0,end_dim=-1):Returnsuniquedimensionsdatabasedonhasharray.|-get_all_values(start_dim=0,end_dim=-1):Returnsallvaluesbasedonhasharrayandspecifieddimensions.|-group_equal_values(start_dim=0,end_dim=-1):Groupsequalvaluesbasedonhasharrayandspecifieddimensions.|-sort_by_hash(ascending=False):Sortsthehasharraybyhashvaluesinascendingordescendingorder.|-sort_by_quantity(ascending=False):Sortsthehasharraybyquantityvaluesinascendingordescendingorder.||Methodsdefinedhere:||__init__(self,a,unordered=True)|InitializesanewinstanceoftheHashSortclass.||Parameters:|-a(numpy.ndarray):Theinputmulti-dimensionalNumPyarray.|-unordered(bool):IfTrue,willcreatetheindexarraywithmultiprocessing||generate_hash_array(self,last_dim=None)|Generatesahasharraybasedontheprovidedarrayandoptionallast_dim.||Parameters:|-last_dim(int,optional):Thelastdimensiontoconsider.IfNone,usesthelastdimensionofthearray.||Returns:|-HashSort:ThecurrentHashSortinstance.||get_all_values(self,start_dim=0,end_dim=-1)|Returnsallvaluesbasedonhasharrayandspecifieddimensions.||Parameters:|-start_dim(int,optional):Thestartingdimensionindextoconsider.|-end_dim(int,optional):Theendingdimensionindextoconsider.||Returns:|-numpy.ndarray:Allvaluesbasedonthespecifieddimensions.||get_shape_array(self,last_dim)|Returnstheshapearraybasedontheprovidedlastdimension.||Parameters:|-last_dim(int):Thelastdimensiontoconsider.||Returns:|-Tuple:Atuplecontainingtheshapearrayandtheproductofarrayshapeelementsfromlast_dimonwards.||get_unique_dims_data(self,start_dim=0,end_dim=-1)|Returnsuniquedimensionsdatabasedonhasharray.||Parameters:|-start_dim(int,optional):Thestartingdimensionindextoconsider.|-end_dim(int,optional):Theendingdimensionindextoconsider.||Returns:|-List[numpy.ndarray]:Alistcontaininguniquedimensionsdata.||group_equal_values(self,start_dim=0,end_dim=-1)|Groupsequalvaluesbasedonhasharrayandspecifieddimensions.||Parameters:|-start_dim(int,optional):Thestartingdimensionindextoconsider.|-end_dim(int,optional):Theendingdimensionindextoconsider.||Returns:|-numpy.ndarray:Groupedvaluesbasedonthespecifieddimensions.||sort_by_absolut_index(self,ascending=True)|Sortsthehasharraybyabsoluteindex(np.flatten()/np.ravel()inascendingordescendingorder.||Parameters:|-ascending(bool,optional):IfTrue,sortsinascendingorder;otherwise,sortsindescendingorder.||Returns:|-numpy.ndarray:Thesortedhasharray.||sort_by_hash(self,ascending=False)|Sortsthehasharraybyhashvaluesinascendingordescendingorder.||Parameters:|-ascending(bool,optional):IfTrue,sortsinascendingorder;otherwise,sortsindescendingorder.||Returns:|-numpy.ndarray:Thesortedhasharray.||sort_by_quantity(self,ascending=False)|Sortsthehasharraybyquantityvaluesinascendingordescendingorder.||Parameters:|-ascending(bool,optional):IfTrue,sortsinascendingorder;otherwise,sortsindescendingorder.||Returns:|-numpy.ndarray:Thesortedhasharray.