#python #arrays #numpy #tensorflow
#python #массивы #numpy #tensorflow
Вопрос:
У меня есть массив A
с формой (N,). Я беру N = 5 для иллюстрации:
A = np.array([0,1,1,0,1])
И я хочу преобразовать его в следующую матрицу NxN B
. Решения как в NumPy, так и в Tensorflow хороши, но последнее предпочтительнее.
B = np.array([[0,1,1,0,1],
[0,1,1,0,1],
[0,1,1,0,1],
[0,0,0,0,1],
[0,0,0,0,1]])
Одно из решений может состоять из следующих шагов:
- Повторите массив
A
N раз - Перебирайте каждую строку
i
. Ищите индекс последнего нуля доi-th
элемента этой строки. - Замените все элементы, предшествующие этому индексу, нулями.
Еще одна иллюстрация с N = 10:
D = np.array([0,1,1,1,0,0,1,1,0,0])
E = np.array([[0,1,1,1,0,0,1,1,0,0],
[0,1,1,1,0,0,1,1,0,0],
[0,1,1,1,0,0,1,1,0,0],
[0,1,1,1,0,0,1,1,0,0],
[0,0,0,0,0,0,1,1,0,0],
[0,0,0,0,0,0,1,1,0,0],
[0,0,0,0,0,0,1,1,0,0],
[0,0,0,0,0,0,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0]])
Комментарии:
1. Почему пятая строка B должна быть [0,0,0,0,1], если 5-й элемент равен 1. И в чем идея C?
2. Для B) это потому, что пятый элемент A равен 1. таким образом, 5-я строка и 5-й элемент B равны 1, поэтому он остается таким. Мне нужно изменить только перед i-м элементом, если значение равно нулю. C) — это просто инкрементная версия. Оба могут быть решением моей проблемы
3. Требуется дополнительное объяснение
4. Я упростил (без матрицы C) и добавил дополнительные пояснения. Надеюсь, теперь это понятнее
5. Мое предыдущее описание было ошибочным — извините. Я изменил описание шагов.
Ответ №1:
A = np.array([0,1,1,0,1])
N = A.shape[0]
column = (A > 0).reshape((N, 1))
mask = np.ones((N, N), dtype=np.bool)
mask = np.where(column, False, np.tril(mask, -1))
mask = np.cumsum(mask, axis=0)
B = np.where(mask, 0, np.tile(A, (N, 1)))
[[0 1 1 0 1]
[0 1 1 0 1]
[0 1 1 0 1]
[0 0 0 0 1]
[0 0 0 0 1]]
Объяснение
- Вычислить нижнюю треугольную матрицу
[[False False False False False]
[ True False False False False]
[ True True False False False]
[ True True True False False]
[ True True True True False]]
- Найдите единицы в A и заполните соответствующие строки значением False
[[False False False False False]
[False False False False False]
[False False False False False]
[ True True True False False]
[False False False False False]]
- Вычислите совокупную сумму, чтобы установить нули для всех строк ниже. Это маска всех элементов, которые должны быть обнулены
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[1 1 1 0 0]
[1 1 1 0 0]]
- Повторите массив N раз
[[0 1 1 0 1]
[0 1 1 0 1]
[0 1 1 0 1]
[0 1 1 0 1]
[0 1 1 0 1]]
- Маскируйте его элементы
[[0 1 1 0 1]
[0 1 1 0 1]
[0 1 1 0 1]
[0 0 0 0 1]
[0 0 0 0 1]]
Ответ №2:
@rafiko1 ваше объяснение мне все еще непонятно. Но попробуйте следующее.
import numpy as np
nn = 5
A = np.array([0,1,1,0,1])
#A = np.array([0,1,1,1,0,0,1,1,0,0])
# we create the matrix B and set required entries to zero
B = np.repeat(A.reshape(1,nn),nn,axis=0)
# test condition:
# test if the ith element in the ith row is zero
# this is accomplished using np.diag
boolarr = np.diag(B==0)
# this gives us the row index in B where the condition is true
idx_b_rows = np.where(boolarr == True)
# get indices of entries before diagonal
idx_lower_rows,idx_lower_cols = np.tril_indices(nn,k=-1)
# get the indices of the entries of idx_b_rows in idx_lower_rows
idx = np.where(np.in1d(idx_lower_rows,idx_b_rows))[0]
# set the entries before the diagonal to zero
B[idx_lower_rows[idx],idx_lower_cols[idx]] = 0
print(B)