numpy矩阵排名不正确的结果

时间:2016-04-25 14:29:32

标签: python numpy matrix rank

我使用numpy.linalg.matrix_rank()时遇到了一个奇怪的问题 我有一个矩阵A,它有三列和> 100行。 A由0和1组成。当我使用numpy.linalg.matrix_rank(A)时,我得到了answer=3,这是正确的 但是,当我向A添加一个长度相同的新列(A现在有四个colunms)时,使用numpy.linalg.matrix_rank(A)我得到answer=1这没有任何意义。新列中的数字为数千。所有数据类型都是float32。

有谁知道问题出在哪里?谢谢!

这是一个随机生成的例子。这是一个40 * 3阵列A.

array([[ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 0., 0., 1.], [ 1., 0., 1.], [ 1., 1., 1.]], dtype=float32)

numpy.linalg.matrix_rank(A)是3。

现在,我添加了第四列,A现在是:

array([[  6.42096562e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  2.15370996e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  1.28050068e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  3.20350176e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  4.26681055e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  1.55057520e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  6.82897266e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  5.29479727e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  2.54858457e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  9.82017109e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  4.03392627e+03,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  2.24184062e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  6.90389688e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  2.75718145e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  6.67467109e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  4.78061758e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  1.52730410e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  9.13073359e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  1.51932471e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  9.27319297e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  7.41743359e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  7.98595469e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  3.40574414e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  3.12823730e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  5.66580273e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  4.53152070e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  9.84440938e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  7.13604375e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  3.59290312e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  8.91415820e+03,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  5.73751992e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  3.96208867e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  2.06492324e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  1.50155918e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  6.47758789e+02,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  9.27601094e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  9.77911621e+03,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  5.01128320e+04,   0.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  7.21259922e+04,   1.00000000e+00,   0.00000000e+00,
      1.00000000e+00],
   [  6.10147461e+03,   1.00000000e+00,   1.00000000e+00,
      1.00000000e+00]], dtype=float32)

numpy.linalg.matrix_rank(A)是2.这可能吗?

1 个答案:

答案 0 :(得分:5)

" ...这没有任何意义。" 实际上,如果你知道matrix_rank 估计排名的方式,那么合理。 matrix_rank只计算矩阵的singular values的数量不大约为0.如果奇异值相对于最大奇异值较小,则将其视为0。当您在数千"中添加包含数字"的第四列时,您会添加一个大的奇异值。与新的大值相比,三个原始奇异值较小,因此它们被认为是0并且不计入等级。

这是一个例子。 A是一个0和1的数组。 B是通过将包含100000的列附加到A

来创建的
In [217]: np.random.seed(123)

In [218]: A = np.random.randint(0, 2, size=(100, 3)).astype(np.float32)

In [219]: B = np.hstack((A, 100000*np.ones((A.shape[0], 1)))).astype(np.float32)

正如预期的那样,A排名第3位:

In [220]: np.linalg.matrix_rank(A)
Out[220]: 3

以下是A

的奇异值
In [221]: np.linalg.svd(A)[1]
Out[221]: array([ 9.98757744,  5.41796255,  4.88814735], dtype=float32)

与您的示例一样,B的排名为1:

In [222]: np.linalg.matrix_rank(B)
Out[222]: 1

我们可以看到B有一个比其他三个值大得多的奇异值。幅度差异足以使matrix_rank认为较小的奇异值约为0:

In [223]: np.linalg.svd(B)[1]
Out[223]: 
array([  1.00000000e+06,   5.45980692e+00,   4.90207911e+00,
         4.59457588e+00], dtype=float32)

请注意,matrix_rank会考虑数据类型。如果将B转换为64位浮点,则由matrix_rank计算的等级为4:

In [226]: np.linalg.matrix_rank(B.astype(np.float64))
Out[226]: 4