Установите значения в строке равными нулю перед значением индекса строки [NumPy или Tensorflow]

#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]])
 

Одно из решений может состоять из следующих шагов:

  1. Повторите массив A N раз
  2. Перебирайте каждую строку i . Ищите индекс последнего нуля до i-th элемента этой строки.
  3. Замените все элементы, предшествующие этому индексу, нулями.

Еще одна иллюстрация с 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]]
 

Объяснение

  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]]
 
  1. Найдите единицы в 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]]
 
  1. Вычислите совокупную сумму, чтобы установить нули для всех строк ниже. Это маска всех элементов, которые должны быть обнулены
 [[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]]
 
  1. Повторите массив 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]]
 
  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)