为什么选择元素时numpy矩阵和numpy数组之间的区别

时间:2018-01-04 06:46:30

标签: numpy

我有一个计算矩阵

from numpy import matrix
vec=matrix([[  4.79263398e-01+0.j        ,  -2.94883960e-14+0.34362808j,           
     5.91036823e-01+0.j        ,  -2.06730654e-14+0.41959935j,
      -3.20298698e-01+0.08635809j,  -5.97136351e-02+0.22325523j],
    [  9.45394208e-14+0.34385164j,   4.78941900e-01+0.j        ,
       1.07732017e-13+0.41891016j,   5.91969770e-01+0.j        ,
      -6.06877417e-02-0.2250884j ,   3.17803028e-01+0.08500215j],
    [  4.63795513e-01-0.00827114j,  -1.15263719e-02+0.33287485j,
      -2.78282097e-01-0.20137267j,  -2.81970922e-01-0.1980647j ,
       9.26109539e-02-0.38428445j,   5.12483437e-01+0.j        ],
    [ -1.15282610e-02+0.33275927j,   4.63961516e-01-0.00826978j,
      -2.84077490e-01-0.19723838j,  -2.79429184e-01-0.19984041j,
      -4.42104809e-01+0.25708681j,  -2.71973825e-01+0.28735795j],
    [  4.63795513e-01+0.00827114j,   1.15263719e-02+0.33287485j,
      -2.78282097e-01+0.20137267j,   2.81970922e-01-0.1980647j ,
       2.73235786e-01+0.28564581j,  -4.44053596e-01-0.25584307j],
    [  1.15282610e-02+0.33275927j,   4.63961516e-01+0.00826978j,
       2.84077490e-01-0.19723838j,  -2.79429184e-01+0.19984041j,
       5.11419878e-01+0.j        ,  -9.22028113e-02-0.38476356j]])

我想获得第二行,第三列元素

  vec[1][2]
  IndexError: index 1 is out of bounds for axis 0 with size 1 

切片效果很好

  vec[1,2]
  (1.07732017e-13+0.41891015999999998j)

我的第一个问题为什么第一种方式在这种情况下不起作用?它在我使用之前就已经有效了。

第二个问题是:切片的结果是一个数组,如何使它成为一个没有括号的复数值?我的经验是使用

 vec[1,2][0]

但是它再次在这里工作。

我试着在numpy数组上开始做所有事情,那些不能在numpy数组上工作的numpy数组的方法。为什么会有这样的差异?

1 个答案:

答案 0 :(得分:2)

关键区别在于matrix始终是2d。 (这应该是MATLAB用户所熟悉的。)

In [85]: mat = np.matrix('1,2;3,4')
In [86]: mat
Out[86]: 
matrix([[1, 2],
        [3, 4]])
In [87]: mat.shape
Out[87]: (2, 2)
In [88]: mat[1]
Out[88]: matrix([[3, 4]])
In [89]: _.shape
Out[89]: (1, 2)

选择一行mat会返回一个矩阵 - 一行一行。应该清楚的是,它不能再用[1]索引。

使用元组进行索引会返回标量:

In [90]: mat[1,1]
Out[90]: 4
In [91]: type(_)
Out[91]: numpy.int32

作为一般规则,np.matrix上的操作会返回矩阵或标量,而不是np.ndarray

另一个关键点是mat[1][1]不是一个numpy操作。它是两个,mat[1]后跟另一个[1]。想象一下,在没有numpy的任何特殊知识的情况下成为一名Python解释器。你会如何评价这个表达?

现在提出复杂的问题:

In [92]: mat = np.matrix('1+3j, 2;-2, 2+1j')
In [93]: mat
Out[93]: 
matrix([[ 1.+3.j,  2.+0.j],
        [-2.+0.j,  2.+1.j]])
In [94]: mat[1,1]
Out[94]: (2+1j)
In [95]: type(_)
Out[95]: numpy.complex128

正如预期的那样,元组索引返回了一个标量numpy元素。 ()只是numpy显示复数的方式的一部分。

我们可以使用item来获得额外的python等价物,但显示仍然使用()

In [96]: __.item()
Out[96]: (2+1j)
In [97]: type(_)
Out[97]: complex

In [98]: 1+3j
Out[98]: (1+3j)

mat具有A属性,使数组等效。但请注意形状。

In [99]: mat.A        # a 2d array
Out[99]: 
array([[ 1.+3.j,  2.+0.j],
       [-2.+0.j,  2.+1.j]])
In [100]: mat.A1         # a 1d array
Out[100]: array([ 1.+3.j,  2.+0.j, -2.+0.j,  2.+1.j])
In [101]: mat[1].A
Out[101]: array([[-2.+0.j,  2.+1.j]])
In [102]: mat[1].A1
Out[102]: array([-2.+0.j,  2.+1.j])

有时matrix的这种行为很方便。例如,np.sum的行为类似于array keepdims=True

In [108]: np.sum(mat,1)
Out[108]: 
matrix([[ 3.+3.j],
        [ 0.+1.j]])

In [110]: np.sum(mat.A,1, keepdims=True)
Out[110]: 
array([[ 3.+3.j],
       [ 0.+1.j]])