Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

Формирование значений матрицы на основе другой матрицы

#python #python_3x


Хочу написать "красивое" решение заполнение матрицы 1 или 0 на основе значений другой
матрицы.

Входные данные:

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


Результирующая матрица строится таким образом:

Если элемент столбца больше соответствующих bottomD и меньше topD (bottomD < elem
< topD), то в соответствующую ячейку записывается 1. В противном случае записывается 0.

Например, возьмем первый столбец:

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


Значит первый столбец результирующей матрицы будет:

[1,
 1,
 1]


Например, возьмем второй столбец:

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


Значит второй столбец результирующей матрицы будет:

[0,
 1,
 0]


Сейчас я имею вот такое решение, которое работает, но я хочу "решение в одну строку":

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 при таких входных данных имеет вид:

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


В попытках достич своего "идеала" дошел до вот этого:

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


С помощью этого я хотел достичь того, чтобы каждому элементу матрицы соответствовал
нужная пара topD и bottomD. Но на этом этапе результат уже не верен. После того, как
достич этого, я думал просто дописать что-то вроде: 

1 if low < elem < big else 0


Пожалуйста, подскажите.

UPD:

Я достиг того, чего хотел. Вот код:

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


Но он слишком громоздкий. Может есть решение покороче?
    


Ответы

Ответ 1



Через списковое включение наверное будет понятнее (и короче), чем через zip: new_matrix = [[int(bottomD[i] < el < topD[i]) for i, el in enumerate(xs)] for xs in matrix]

Ответ 2



Решение с использованием модуля Numpy: import numpy as np # pip install numpy сначала создадим Numpy матрицы из обычных матриц: m = np.asarray(matrix) top = np.asarray(topD) bottom = np.asarray(bottomD) решение: res = (bottom < m) & (m < top) результат: In [12]: res Out[12]: array([[ True, False, False], [ True, True, True], [ True, False, False]]) или так: In [13]: res.astype('int8') Out[13]: array([[1, 0, 0], [1, 1, 1], [1, 0, 0]], dtype=int8)

Комментариев нет:

Отправить комментарий