python – Generating matrix values ​​based on another matrix

Question:

I want to write a "nice" solution to fill a matrix with 1 or 0 based on the values ​​of another matrix.

Input data:

matrix = [[2, 2, 2],
          [2, 4, 1],
          [2, 6, 0]]
topD = [3, 5, 2]
bottomD = [1, 3, 0]

The resulting matrix is ​​built like this:

If a column element is greater than the corresponding bottomD and less than topD ( bottomD < elem < topD ), then 1 is written to the corresponding cell. Otherwise, 0 is written.

For example, let's take the first column:

1 < 2 < 3
1 < 2 < 3
1 < 2 < 3

So the first column of the resulting matrix will be:

[1,
 1,
 1]

For example, let's take the second column:

3 < 2 < 5
3 < 4 < 5
3 < 6 < 5

So the second column of the resulting matrix will be:

[0,
 1,
 0]

Right now I have a solution like this that works, but I want a "one line solution":

handyStructure = zip(zip(*imgAvg), zip(topD, bottomD))

for column, (big, low) in handyStructure:
    tmpRes = list()

    for elem in column:
        if low < elem < big: tmpRes.append(1)
        else: tmpRes.append(0)

    b.append(tmpRes)

b =  zip(*b)

handyStructure with such input data looks like:

[((2, 2, 2), (3.0, 1.0)), ((2, 4, 6), (5.0, 3.0)), ((2, 1, 0), (2.0, 0.0))]

In an attempt to achieve his "ideal", he came to this:

res = [list(zip(column, (big, low))) for column, (big, low) in handyStructure]

With this, I wanted to achieve that each element of the matrix corresponds to the desired pair of topD and bottomD . But at this stage, the result is no longer correct. After achieving this, I thought to just add something like:

1 if low < elem < big else 0

Please, tell me.

UPD:

I achieved what I wanted. Here is the code:

zip(*[[1 if low < element < big else 0 for element in column] for column, (big, low) in
      zip(zip(*imgAvg), zip(topD, bottomD))])

But it is too cumbersome. Maybe there is a shorter solution?

Answer:

Solution using Numpy module:

import numpy as np   #  pip install numpy

first let's create Numpy matrices from regular matrices:

m = np.asarray(matrix)
top = np.asarray(topD)
bottom = np.asarray(bottomD)

solution:

res = (bottom < m) & (m < top)

result:

In [12]: res
Out[12]:
array([[ True, False, False],
       [ True,  True,  True],
       [ True, False, False]])

or like this:

In [13]: res.astype('int8')
Out[13]:
array([[1, 0, 0],
       [1, 1, 1],
       [1, 0, 0]], dtype=int8)
Scroll to Top