在Python中修改块矩阵

时间:2015-02-18 00:49:54

标签: python numpy matrix

我想采用矩阵并修改它的块。例如,对于4x4矩阵,{1,2},{1,2}块位于左上象限(下面的[0,1; 4,5])。如果我们重新排列矩阵,那么{4,1},{4,1}块是左上象限,因此第4行/列位于第1位,第1列位于第2位。

让我们制作一个4x4矩阵:

a = np.arange(16).reshape(4, 4)
print(a)

## [[ 0  1  2  3]
##  [ 4  5  6  7]
##  [ 8  9 10 11]
##  [12 13 14 15]]

现在,一种选择块的方法,我指定预先想要的行/列,如下所示:

C=[3,0]
a[[[C[0],C[0]],[C[1],C[1]]],[[C[0],C[1]],[C[0],C[1]]]]

## array([[15, 12],
##        [ 3,  0]])

这是另一种方式:

a[C,:][:,C]

## array([[15, 12],
##        [ 3,  0]])

然而,如果我有一个2x2阵列,请将其命名为b,设置

a[C,:][:,C]=b

不起作用,但

a[[[C[0],C[0]],[C[1],C[1]]],[[C[0],C[1]],[C[0],C[1]]]]=b

确实

这是为什么?这是第二种最有效的方式吗?谢谢!

1 个答案:

答案 0 :(得分:1)

numpy docs的相关部分是 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#purely-integer-array-indexing 高级数组索引。

将该示例改编为您的案例:

In [213]: rows=np.array([[C[0],C[0]],[C[1],C[1]]])
In [214]: cols=np.array([[C[0],C[1]],[C[0],C[1]]])

In [215]: rows
array([[3, 3],
       [0, 0]])

In [216]: cols
array([[3, 0],
       [3, 0]])

In [217]: a[rows,cols]
array([[15, 12],
       [ 3,  0]])

由于广播,您不需要重复重复索引,因此:

a[[[3],[0]],[3,0]]

做得很好。 np.ix_是一个方便的功能,只产生这样一对:

np.ix_(C,C) 
(array([[3],
        [0]]), 
 array([[3, 0]]))

因此简短的回答是:

a[np.ix_(C,C)]

相关函数是meshgrid,它构造完整的索引数组:

a[np.meshgrid(C,C,indexing='ij')]

np.meshgrid(C,C,indexing='ij')与您的[rows, cols]相同。有关'ij'参数的重要性,请参阅函数doc。

np.meshgrid(C,C,indexing='ij',sparse=True)生成与np.ix_相同的数组对。

我认为计算速度存在严重差异。显然有些人需要更少的打字。

a[:,C][C,:]适用于查看值,但不适用于修改它们。详细信息与制作views和制作副本的操作有关。简单的答案是,如果要修改值,只使用一层索引。

索引文档:

  

因此,x [ind1,...,ind2,:]在基本切片下就像x [ind1] [...,ind2,:]一样。

因此a[1][3] += 7有效。但该文件也警告

  

警告   对于高级索引,上述情况并非如此。