为什么在选择元素时numpy矩阵和numpy数组之间存在差异

为什么在选择元素时numpy矩阵和numpy数组之间存在差异,numpy,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],

我有一个计算过的矩阵

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数组。为什么会有这样的差异?

关键的区别在于
矩阵总是二维的,总是二维的。(这应该是MATLAB用户所熟悉的。)

选择一行
mat
将返回一个矩阵-一个1行矩阵。应该清楚的是,不能使用
[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]
。想象自己是一个Python解释器,没有任何关于
numpy
的专门知识。你如何评价这个表达式

现在来看复杂的问题:

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等效项,但显示仍然使用()

mat
具有
一个
属性,该属性提供了数组的等效值。但是注意形状

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])
有时,矩阵的这种行为很方便。例如,
np.sum
的作用类似于
数组
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]])

您是否查看了
vec[1]
及其形状?请记住
vec[1][2]
首先执行
x=vec[1]
,然后执行
x[2]
。这是两个python索引步骤
vec[1,2]
是一个索引步骤。在编制索引时,特别是使用数组时,请密切注意形状。这是
矩阵
类的一个怪癖,顺便提一下,也是我强烈建议不要使用它的原因之一。在
数组
中,双索引的工作方式与预期的一样,因为它们在这方面的行为类似于嵌套列表<代码>矩阵
es不会,它们顽固地返回2D。顺便说一句,在处理数组时,
[1,2]
[1][2]
更可取,因为@hpaulj解释说后者会创建不必要的中间层。
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])
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]])