Home > Back-end >  Cell-wise most dominant value across 2d array
Cell-wise most dominant value across 2d array

Time:06-11

I have multiple 2d arrays like this for example

A = [[-1, -1, 0, 1, -1], [1, 1, 0, -1, -1], [-1, -1, -1, -1, -1], [-1, 1, -1, -1, 0]]
B = [[-1, -1, 0, 1, -1], [1, -1, 0, -1, -1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]
C = [[0, -1, 0, 1, -1], [1, -1, 0, -1, -1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]
D = [[-1, -1, 0, 1, 0], [0, 0, -1, 0, 1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]

I need to find the most dominant value across each cell so the output would be like -

E = [[-1 -1 0 1 -1],[1 -1 0 -1 -1],[0 1 -1 1 -1],[-1 1 -1 -1 -1]]

I can definitely loop through each of these arrays but I was looking for a vectorised approach. The arrays can be around 10-11 in number and dimensions are around 900X900.

Is it possible to solve this using basic list comprehension?

CodePudding user response:

You can zip all arrays and in each cell of rows and columns of all arrays compute count and find max and save max like below:

import numpy as np
def cell_wise_cnt(arrs):
    n_row = 0
    res = np.empty((len(arrs[0]),len(arrs[0][0])))
    for row in zip(*arrs):
        arr = np.array(row)
        num_col = len(arr[0])
        for col in range(num_col):
            nums, cnts = np.unique(arr[:,col], return_counts=True)
            srt = sorted(zip(nums, cnts), key= lambda x: x[1])
            res[n_row, col] = srt[-1][0]
        n_row  = 1
    return res

Output:

>>> cell_wise_cnt(arrs = (A,B,C,D))

array([[-1., -1.,  0.,  1., -1.],
       [ 1., -1.,  0., -1., -1.],
       [ 0.,  1., -1.,  1., -1.],
       [-1.,  1., -1., -1., -1.]])

CodePudding user response:

Using list comprehension gets a little Hacky. Gave some work, but did it.

Basically you have to use nested child list comprehension, and the arrays must be of the same size for this to work.

To work with a matrix, it would need just 1 nested list, but as we are working with a list of matrixes, it'll be 3 dimensional, so 2 nested childs.

The import mode I used to get the most dominant value.

from statistics import mode


A = [[-1, -1, 0, 1, -1], [1, 1, 0, -1, -1], [-1, -1, -1, -1, -1], [-1, 1, -1, -1, 0]]
B = [[-1, -1, 0, 1, -1], [1, -1, 0, -1, -1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]
C = [[0, -1, 0, 1, -1], [1, -1, 0, -1, -1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]
D = [[-1, -1, 0, 1, 0], [0, 0, -1, 0, 1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]

matrixes = [A, B, C, D]

result = [[mode([x[k][j] for i, x in enumerate(matrixes)]) for j in range(len(matrixes[0][0]))] for k in range(len(matrixes))]

print(result)

result:

[[-1, -1, 0, 1, -1], [1, -1, 0, -1, -1], [0, 1, -1, 1, -1], [-1, 1, -1, -1, -1]]
  • Related