使用已排序的一维数组对方形数组重新排序

Reorder a square array using a sorted 1D array

假设我有一个对称的 n×n 数组 A 和一个长度为 n 的一维数组 x,其中 A 的 rows/columns 对应于x 的条目和 x 是有序的。现在假设 Ax 都是随机重新排列的,因此 rows/columns 仍然对应,但它们不再按顺序排列。如何操作 A 来恢复正确的顺序?

例如:x = array([1, 3, 2, 0])

A = array([[1, 3, 2, 0],
           [3, 9, 6, 0],
           [2, 6, 4, 0],
           [0, 0, 0, 0]])

所以本例中从xA的映射是A[i][j] = x[i]*x[j]x 应该像 array([0, 1, 2, 3]) 一样排序,我想到达

A = array([[0, 0, 0, 0],
           [0, 1, 2, 3],
           [0, 2, 4, 6],
           [0, 3, 6, 9]])

您可以使用 argsort 和花哨的索引:

idx = np.argsort(x)
A2 = A[idx[None], idx[:,None]]

输出:

array([[0, 0, 0, 0],
       [0, 1, 2, 3],
       [0, 2, 4, 6],
       [0, 3, 6, 9]])

一个简单的实现是

idx = np.argsort(x)
A = A[idx, :]
A = A[:, idx]

另一种可能性是(所有归功于@mathfux):

A[np.ix_(idx, idx)]

我猜想 OP 正在寻找一种灵活的方法来使用索引来同时对他的映射的行和列进行排序。更重要的是,OP 可能有兴趣以相反的方式进行,即如果丢失了映射的查找和初始视图。

def mapping(x, my_map, return_index=True, return_inverse=True):
    idx = np.argsort(x)
    out = my_map(x[idx], x[idx])
    inv = np.empty_like(idx)
    inv[idx] = np.arange(len(idx))
    return out, idx, inv

x = np.array([1, 3, 2, 0])
a, idx, inv = mapping(x, np.multiply.outer) #sorted mapping
b = np.multiply.outer(x, x) #straight mapping

print(b)
>>> [[1 3 2 0]
     [3 9 6 0]
     [2 6 4 0]
     [0 0 0 0]]
print(a)
>>> [[0 0 0 0]
     [0 1 2 3]
     [0 2 4 6]
     [0 3 6 9]]

np.array_equal(b, a[np.ix_(inv, inv)]) #sorted to straight
>>> True
np.array_equal(a, b[np.ix_(idx, idx)]) #straight to sorted
>>> True