Как получить диагональные компоненты массивного трехмерного массива?
У меня есть 3-D массив, как
a = np.array(
[[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]]
)
и я хочу получить диагональный компонент из этого массива, я имею в виду,
>> np.array([a[i,i,:] for i in range(min(a.shape[0], a.shape[1]))])
array([[1, 2],
[7, 8]])
Есть ли более быстрый способ сделать то же самое, что и выше?
2 ответа
Вместо np.diagonal
Вы также можете использовать np.einsum
:
>>> a = np.arange(1,9).reshape(2,2,2)
>>> d = np.einsum('iij->ij', a)
>>> d
array([[1, 2],
[7, 8]])
Преимущество: он возвращает доступное для записи представление, поэтому может использоваться для прямой манипуляции с диагональю в исходном массиве:
>>> d[0,0] = -3
>>> a
array([[[-3, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]]])
np.diagonal
работает для массивов с более чем двумя измерениями, для которых вы можете указать ось для просмотра с параметрами axis1
а также axis2
для вашего случая работает значение по умолчанию (axis1=0, axis2=1):
np.diagonal(a, axis1=0, axis2=1).T
# array([[1, 2],
# [7, 8]])
Это также работает для массивов, которые имеют разные размеры на двух осях, рассматриваемых:
a = np.array(
[[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]],
[[9, 10],
[11, 12]]]
)
np.diagonal(a).T
#array([[1, 2],
# [7, 8]])
a = np.array(
[[[1, 2],
[3, 4],
[9, 10]],
[[5, 6],
[7, 8],
[11, 12]]]
)
np.diagonal(a).T
#array([[1, 2],
# [7, 8]])
Или вы можете использовать расширенную индексацию:
Создайте индекс диапазона:
idx = np.arange(min(a.shape[:2]))
idx
# array([0, 1])
Индексируйте первое и второе измерение, используя целочисленные массивы, а третье измерение - срезом:
a[idx, idx, :]
#array([[1, 2],
# [7, 8]])