How can I get the sets of a cube/3d numpy array in python

102 Views Asked by At

I have an initial code that discretizes a cube into a binary one. Starting with a cube NxMxZ the binary cube will be of dimensions N-1xMxZ-1 using the process I've done, here:


def discretize_cube(cube):
    """
    Discretizes a 3D cube and returns a binary cube.

    Args:
    cube (np.array): A 3D numpy array representing the original cube.

    Returns:
    np.array: A 3D numpy array representing the discretized and binary cube.
    """
    empty_cube = np.zeros(shape=(len(cube)-1,len(cube[0]),len(cube[0][0])-1),
                      dtype='int16')

    for z in range(0, len(cube)):
        for x in range(0,len(cube[0])):
            for y in range(0, len(cube[0][0])):

                if ((y+1 < len(cube[0][0])) & (z+1 < len(cube))) :
                    if (((cube[z][x][y] < cube[z][x][y+1]) & 
                        (cube[z][x][y] < cube[z+1][x][y])) | (
                        (cube[z][x][y] > cube[z][x][y+1]) & 
                        (cube[z][x][y] < cube[z+1][x][y])) | (
                        (cube[z][x][y] == cube[z][x][y+1]) & 
                        (cube[z][x][y] < cube[z+1][x][y]))):

                        empty_cube[z][x][y]=1
                        
                    elif (((cube[z][x][y] > cube[z][x][y+1]) &
                          (cube[z][x][y] > cube[z+1][x][y])) | (
                        (cube[z][x][y] < cube[z][x][y+1]) &
                        (cube[z][x][y] > cube[z+1][x][y])) | (
                        (cube[z][x][y] == cube[z][x][y+1]) &
                        (cube[z][x][y] > cube[z+1][x][y]))):

                        empty_cube[z][x][y]=-1
                        
                    else:
                        empty_cube[z][x][y]=0

    binary_cube=[]
    count=0
    
    for z in empty_cube:
        count=count+1
        matrix_dt_copy = z.copy()
        matrix_dt = np.transpose(matrix_dt_copy)

        for i in range(0,len(matrix_dt)):

            counts_dict={}

            matrix_dt_1 = np.count_nonzero(matrix_dt[i]==1)
            counts_dict[1]=matrix_dt_1

            matrix_dt_m1 = np.count_nonzero(matrix_dt[i]==-1)
            counts_dict[-1]=matrix_dt_m1

            matrix_dt_0 = np.count_nonzero(matrix_dt[i]==0)
            counts_dict[0]=matrix_dt_0

            median = st.median(counts_dict.values())

            key_use = get_key(median,counts_dict,i,matrix_dt)

            for j in range(0,len(matrix_dt[0])):
                if matrix_dt[i][j] == key_use:
                    matrix_dt[i][j]=1    
                else:
                    matrix_dt[i][j]=0

        binary_matrix = np.transpose(matrix_dt)
        binary_cube.append(binary_matrix)

    binary_cube_final=[matrix.tolist() for matrix in binary_cube]
    binary_cube_final=np.array(binary_cube_final)
    #new_cube= np.array([np.transpose(matrix) for matrix in binary_cube_final])
    return binary_cube_final

def get_key(val,dic,i,matriz):
"""
This function receives a value, a dictionary, an index and a matrix as inputs and returns a key from the dictionary
that matches the given value. If there is more than one key that matches the value, it will return the first one that
appears in the matrix.

Parameters:
val (int): A value to look for in the dictionary.
dic (dict): A dictionary where the keys are integers and the values are the number of occurrences of those integers
            in a given list.
i (int): An index representing the current row of the matrix being analyzed.
matriz (numpy.ndarray): A 2D numpy array where each row represents a list of integers.

Returns:
int: A key from the dictionary that matches the given value.
"""
vazio=[]
conta=[]

if list(dic.values()).count(val)>1 and val != 0:
    vazio = [k for k, v in dic.items() if v == val]
    
    for col in matriz[i]:
        if col in vazio and len(conta)==0:
            conta.append(1)
            valor_f=col
            return valor_f
            print(valor_f)
        elif len(conta)!=0:
            break
    
elif list(dic.values()).count(val)>1 and val == 0: 
    for key, value in dic.items():
        if value != 0:
            valor_f=key
            return valor_f
else:
    for key, value in dic.items():
        if val == value:
            valor_f=key
            return valor_f
            print(valor_f)

Having the binary cube I want to get the sets of ones or in another words all the possible combinations of 1´s to extract the triclusters from that. I've only been able to do it with a matrix, where for that I've got this code and don't know if it is all okay:


import itertools

def get_all_sets(matrix):
    indexes = []
    for row in range(len(matrix)):
        for col in range(len(matrix[0])):
            if matrix[row][col] == 1:
                indexes.append((row, col))
    #print(indexes)
    all_sets = []
    for i in range(1, len(indexes) + 1):
        for combination in itertools.combinations(indexes, i):
            #print(combination)
            all_sets.append(combination)

    return all_sets

For that if I use this matrix as example:


test = np.array([[1, 0, 1, 1],
        [0, 1, 0, 0],
        [0, 0, 0, 0]])

I will get something like:

 ((0, 2),),
 ((0, 3),),
 ((1, 1),),
 ((2, 2),),
 ((0, 0), (0, 2)),
 ((0, 0), (0, 3)),
 ((0, 0), (1, 1)),
 ((0, 0), (2, 2)),
 ((0, 2), (0, 3)),
 ((0, 2), (1, 1)),
 ((0, 2), (2, 2)),
 ((0, 3), (1, 1)),
 ((0, 3), (2, 2)),
 ((1, 1), (2, 2)),
 ((0, 0), (0, 2), (0, 3)),
 ((0, 0), (0, 2), (1, 1)),
 ((0, 0), (0, 2), (2, 2)),
 ((0, 0), (0, 3), (1, 1)),
 ((0, 0), (0, 3), (2, 2)),
 ((0, 0), (1, 1), (2, 2)),
 ((0, 2), (0, 3), (1, 1)),
 ((0, 2), (0, 3), (2, 2)),
 ((0, 2), (1, 1), (2, 2)),
 ((0, 3), (1, 1), (2, 2)),
 ((0, 0), (0, 2), (0, 3), (1, 1)),
 ((0, 0), (0, 2), (0, 3), (2, 2)),
 ((0, 0), (0, 2), (1, 1), (2, 2)),
 ((0, 0), (0, 3), (1, 1), (2, 2)),
 ((0, 2), (0, 3), (1, 1), (2, 2)),
 ((0, 0), (0, 2), (0, 3), (1, 1), (2, 2))]

where an (X,Y) represents the indexes of a single 1. what can I do to overcome this?

0

There are 0 best solutions below