Я не уверен, как это сделать, пример:
array([[1, 1],
[2, 2],
[3, 3]])
преобразовать его в это:
array([[1, 1, 0, 0],
[0, 2, 2, 0],
[0, 0, 3, 3]])
np.diag
работает только с массивом от 1d до диагональной матрицы.
Я могу получить это с помощью итеративного подхода с циклом for и фрагментами, но я чувствую, что может быть лучший подход.
triu
и tril
Numpy.import numpy as np
x=np.array([[1],
[2 ],
[3]])
diagonal_length = len(x)
repeats = 2
y = x*np.ones(diagonal_length+(repeats-1))
print("Intermediate step:\n", y)
z = np.tril(np.triu(y,0),repeats-1)
print("\nOutput:\n",z)
Сначала создается полная сетка, высота которой равна длине вашей диагонали, а ширина немного шире, чтобы вместить несколько диагоналей.
Intermediate step:
[[1. 1. 1. 1.]
[2. 2. 2. 2.]
[3. 3. 3. 3.]]
Затем он использует triu
и tril
для обнуления недиагональных областей.
В приведенном выше коде длина диагонали автоматически рассчитывается на основе введенных вами данных, и вы можете вручную указать, сколько повторений вы хотите.
Output:
[[1. 1. 0. 0.]
[0. 2. 2. 0.]
[0. 0. 3. 3.]]
а массив 2d может быть любого размера?
Вы можете использовать расширенное индексирование с некоторыми самогенерируемыми индексами:
import numpy as np
arr = np.array([[1, 1], [2, 2], [3, 3]])
h, w = arr.shape
w_out = h + w - 1
out = np.zeros((h, w_out), dtype=arr.dtype)
rows = np.arange(h)[:, None]
cols = rows + np.arange(w)
out[rows, cols] = arr
вне:
array([[1, 1, 0, 0],
[0, 2, 2, 0],
[0, 0, 3, 3]])
Промежуточные продукты:
>>> rows
array([[0],
[1],
[2]])
>>> cols
array([[0, 1],
[1, 2],
[2, 3]])
Что, если это не повторяющийся массив 1d?