首页 > 解决方案 > 镜像一个 numpy ndarray

问题描述

我有一个尺寸为 (N * N * M) 的 numpy Ndarray,并希望有效地将其镜像到主对角线上。对于 N=1,我做了以下事情:

A = np.array([[1, 0, 6, 5], [0, 2, 0, 0], [1, 0, 2, 0], [0, 1, 0, 3]])
A = np.tril(A) + np.triu(A.T, 1)
'''
From:
array([[1, 0, 6, 5],
       [0, 2, 0, 0],
       [1, 0, 2, 0],
       [0, 1, 0, 3]])
To:
array([[1, 0, 1, 0],
       [0, 2, 0, 1],
       [1, 0, 2, 0],
       [0, 1, 0, 3]])
'''

然而,这个 (np.trilnp.triu) 不适用于更高的维度,例如

A = np.array([[[1], [0], [6], [5]], [[0], [2],[0], [0]], [[1], [0], [2], [0]], [[0], [1], [0], [3]]]) # (4,4,1)
A = np.array([[[1,2], [0,3], [6,5], [5,6]], [[0,3], [2,2],[0,1], [0,3]], [[1,5], [0,2], [2,1], [0,9]], [[0,1], [1,2], [0,2], [3,4]]]) # (4,4,2)

有什么想法可以有效地做到这一点(没有 for 循环)?我不介意你镜像矩阵的底部或顶部三角形

标签: pythonarraysnumpyarray-broadcasting

解决方案


这是一种简单的方法:

import numpy as np

# Example data, shape (4, 4, 2)
a = np.array([[[1, 2], [0, 3], [6, 5], [5, 6]],
              [[0, 3], [2, 2], [0, 1], [0, 3]],
              [[1, 5], [0, 2], [2, 1], [0, 9]],
              [[0, 1], [1, 2], [0, 2], [3, 4]]])
# Lower triangle of ones, shape (4, 4, 1)
tril = np.tril(np.ones(a.shape[:-1], a.dtype))[..., np.newaxis]
# Eye matrix with extra dimension, shape (4, 4, 1)
eye = np.eye(a.shape[0], dtype=a.dtype)[..., np.newaxis]
# Lower triangle
atril = a * tril
# Add upper triangle and remove diagonal that was added twice
result = atril + atril.swapaxes(0, 1) - a * eye
# Check result
print(result[..., 0])
# [[1 0 1 0]
#  [0 2 0 1]
#  [1 0 2 0]
#  [0 1 0 3]]
print(result[..., 1])
# [[2 3 5 1]
#  [3 2 2 2]
#  [5 2 1 2]
#  [1 2 2 4]]

推荐阅读