排列矩阵的行和列
Permute rows and columns of a matrix
假设我有以下 matrix/array:
array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
我想应用以下排列:
1 -> 5
2 -> 4
最后的结果应该是:
array([[1, 1, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 1, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 1, 1, 1]])
现在,一种非常幼稚(且占用大量内存)的方法可能是:
a2 = deepcopy(a1)
a2[0,:] = a1[4,:]
a2[4,:] = a1[0,:]
a = deepcopy(a2)
a2[:,0] = a[:,4]
a2[:,4] = a[:,0]
a3 = deepcopy(a2)
a2[1,:] = a3[3,:]
a2[3,:] = a3[1,:]
a = deepcopy(a2)
a2[:,1] = a[:,3]
a2[:,3] = a[:,1]
但是,我想知道是否有更有效的方法可以做到这一点。 numpy.shuffle 和 numpy.permutation 似乎只置换矩阵的行(而不是同时置换列)。这对我不起作用,因为矩阵是邻接矩阵(表示图),我需要进行排列,这将给我一个与原始图同构的图。此外,我需要进行任意数量的排列(不止一个)。
谢谢!
我找到了一个解决方案来做我想做的事(虽然很贵):
a2 = deepcopy(a1)
first = randint(0, 5, 10)
second = randint(0, 5, 10)
for i in range(len(first)):
a = deepcopy(a2)
a2[first[i],:] = a[second[i],:]
a2[second[i],:] = a[first[i],:]
for i in range(len(first)):
a = deepcopy(a2)
a2[:,first[i]] = a[:,second[i]]
a2[:,second[i]] = a[:,first[i]]
基本上,我在进行 10 次随机切换。但是,我需要多次复制矩阵。无论如何,a2 现在表示与 a1 同构的图。
您可以使用 integer array indexing:
在一行中执行交换
a = np.array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
b = a.copy()
# map 0 -> 4 and 1 -> 3 (N.B. Python indexing starts at 0 rather than 1)
a[[4, 3, 0, 1]] = a[[0, 1, 4, 3]]
print(repr(a))
# array([[1, 1, 1, 0, 0],
# [1, 0, 1, 0, 0],
# [1, 1, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 1, 1, 1]])
请注意,数组索引总是 returns 副本而不是视图 - 没有生成副本的情况下无法交换数组的任意 rows/columns。
在这种特殊情况下,您可以通过使用切片索引来避免复制,returns视图而不是副本:
b = b[::-1] # invert the row order
print(repr(b))
# array([[1, 1, 1, 0, 0],
# [1, 0, 1, 0, 0],
# [1, 1, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 1, 1, 1]])
更新:
您可以使用相同的索引方法来交换列。
c = np.arange(25).reshape(5, 5)
print(repr(c))
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14],
# [15, 16, 17, 18, 19],
# [20, 21, 22, 23, 24]])
c[[0, 4], :] = c[[4, 0], :] # swap row 0 with row 4...
c[:, [0, 4]] = c[:, [4, 0]] # ...and column 0 with column 4
print(repr(c))
# array([[24, 21, 22, 23, 20],
# [ 9, 6, 7, 8, 5],
# [14, 11, 12, 13, 10],
# [19, 16, 17, 18, 15],
# [ 4, 1, 2, 3, 0]])
我在这种情况下使用了不同的示例数组 - 您的版本在执行 row/column 交换后将产生相同的输出,这使得很难理解发生了什么。
假设我有以下 matrix/array:
array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
我想应用以下排列:
1 -> 5
2 -> 4
最后的结果应该是:
array([[1, 1, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 1, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 1, 1, 1]])
现在,一种非常幼稚(且占用大量内存)的方法可能是:
a2 = deepcopy(a1)
a2[0,:] = a1[4,:]
a2[4,:] = a1[0,:]
a = deepcopy(a2)
a2[:,0] = a[:,4]
a2[:,4] = a[:,0]
a3 = deepcopy(a2)
a2[1,:] = a3[3,:]
a2[3,:] = a3[1,:]
a = deepcopy(a2)
a2[:,1] = a[:,3]
a2[:,3] = a[:,1]
但是,我想知道是否有更有效的方法可以做到这一点。 numpy.shuffle 和 numpy.permutation 似乎只置换矩阵的行(而不是同时置换列)。这对我不起作用,因为矩阵是邻接矩阵(表示图),我需要进行排列,这将给我一个与原始图同构的图。此外,我需要进行任意数量的排列(不止一个)。
谢谢!
我找到了一个解决方案来做我想做的事(虽然很贵):
a2 = deepcopy(a1)
first = randint(0, 5, 10)
second = randint(0, 5, 10)
for i in range(len(first)):
a = deepcopy(a2)
a2[first[i],:] = a[second[i],:]
a2[second[i],:] = a[first[i],:]
for i in range(len(first)):
a = deepcopy(a2)
a2[:,first[i]] = a[:,second[i]]
a2[:,second[i]] = a[:,first[i]]
基本上,我在进行 10 次随机切换。但是,我需要多次复制矩阵。无论如何,a2 现在表示与 a1 同构的图。
您可以使用 integer array indexing:
在一行中执行交换a = np.array([[0, 0, 1, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
b = a.copy()
# map 0 -> 4 and 1 -> 3 (N.B. Python indexing starts at 0 rather than 1)
a[[4, 3, 0, 1]] = a[[0, 1, 4, 3]]
print(repr(a))
# array([[1, 1, 1, 0, 0],
# [1, 0, 1, 0, 0],
# [1, 1, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 1, 1, 1]])
请注意,数组索引总是 returns 副本而不是视图 - 没有生成副本的情况下无法交换数组的任意 rows/columns。
在这种特殊情况下,您可以通过使用切片索引来避免复制,returns视图而不是副本:
b = b[::-1] # invert the row order
print(repr(b))
# array([[1, 1, 1, 0, 0],
# [1, 0, 1, 0, 0],
# [1, 1, 0, 1, 1],
# [0, 0, 1, 0, 1],
# [0, 0, 1, 1, 1]])
更新:
您可以使用相同的索引方法来交换列。
c = np.arange(25).reshape(5, 5)
print(repr(c))
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14],
# [15, 16, 17, 18, 19],
# [20, 21, 22, 23, 24]])
c[[0, 4], :] = c[[4, 0], :] # swap row 0 with row 4...
c[:, [0, 4]] = c[:, [4, 0]] # ...and column 0 with column 4
print(repr(c))
# array([[24, 21, 22, 23, 20],
# [ 9, 6, 7, 8, 5],
# [14, 11, 12, 13, 10],
# [19, 16, 17, 18, 15],
# [ 4, 1, 2, 3, 0]])
我在这种情况下使用了不同的示例数组 - 您的版本在执行 row/column 交换后将产生相同的输出,这使得很难理解发生了什么。