使用切片/索引在矩阵内切换Numpy向量

时间:2019-02-17 10:28:56

标签: python pandas numpy

让我们考虑以下矩阵:

[v1 v2 v3 v4 v5 v6] = 
[[1., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 1., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 0., 1.],
[0., 0., 0., 0., 1., 0.]],

其中向量[v2 v3]和[v5 v6]相对于单位矩阵进行切换。

从单位矩阵开始,我们如何使用切片/索引建立先前的矩阵?

如果要明确执行此操作,则应执行以下操作:

x = np.eye(6)
x[[1,2]] = x[[2,1]]
x[[4,5]] = x[[5,6]]

3 个答案:

答案 0 :(得分:1)

(我知道)没有一个函数可以交换列的位置,因为您可以通过发布时的基本切片来实现。您始终可以构建以下功能:

def swap(arr, *tups, copy=False):
  ix = np.array(tups)
  if copy:
    arr = arr.copy()
  arr[ix.ravel()] = arr[ix[:,::-1].ravel()]
  return arr

swap(np.eye(6), (0,2), (1,3))
>> array([[0., 0., 1., 0., 0., 0.],
   [0., 0., 0., 1., 0., 0.],
   [1., 0., 0., 0., 0., 0.],
   [0., 1., 0., 0., 0., 0.],
   [0., 0., 0., 0., 1., 0.],
   [0., 0., 0., 0., 0., 1.]])

但是,如果您想要性能,我建议使用稀疏矩阵。 csr_matrix将非零列存储在indices中,从而使切换列变得容易:

import scipy.sparse as sparse
I = sparse.eye(6, format='csr')
I.indices[[0,2,1,3]] = I.indices[[2,0,3,1]] 
print(I.todense())
>> array([[0., 0., 1., 0., 0., 0.],
   [0., 0., 0., 1., 0., 0.],
   [1., 0., 0., 0., 0., 0.],
   [0., 1., 0., 0., 0., 0.],
   [0., 0., 0., 0., 1., 0.],
   [0., 0., 0., 0., 0., 1.]])

答案 1 :(得分:1)

可扩展到任何N的矢量解决方案:

N=2
s = np.zeros((3*N,3*N))
pattern = [[1,0,0],[0,0,1],[0,1,0]]
s.reshape(N,3,N,3)[range(N),:,range(N),:] = pattern

对于

array([[1., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 0., 1.],
       [0., 0., 0., 0., 1., 0.]])

答案 2 :(得分:0)

像这样吗?

# helper function, swaps two rows
def swaprows(arr, row1, row2):
    temp = arr[row1].copy()
    arr[row1] = arr[row2]
    arr[row2] = temp
    return arr

a = np.eye(6)
a = swaprows(a, 1, 2)
a = swaprows(a, 4, 5)
print(a)
# => 
# [[1. 0. 0. 0. 0. 0.]
#  [0. 0. 1. 0. 0. 0.]
#  [0. 1. 0. 0. 0. 0.]
#  [0. 0. 0. 1. 0. 0.]
#  [0. 0. 0. 0. 0. 1.]
#  [0. 0. 0. 0. 1. 0.]]

请注意,python使用0索引,我想您来自R或Matlab,而您的最后一个代码块将是a)不使用双花括号,并且b)尝试对一个索引进行索引会导致索引超出范围错误在第6个位置的大小为6的数组。