Python:如何在numpy中消除矩阵中的所有零行

Python:如何在numpy中消除矩阵中的所有零行,python,numpy,Python,Numpy,我有一个0和1的numpy数组。 我需要在一次Python移动中提取所有由0组成的行,并保留其余的行 我已经寻找了以前回答这个问题的问题,似乎 此问题与以下问题重复: 但我不理解任何答案。看起来重要的命令是: a[~(a==0).all(1)] 但我根本不明白它是如何提取矩阵的。事实上,当我在代码中使用这一行时,它提取的是数组,而不是2d矩阵 我已经看过了np.all(), 但看起来这只是一个测试 有人能帮我一下吗。这是一个有效的例子,也许不是最有效的: import numpy as np

我有一个0和1的numpy数组。 我需要在一次Python移动中提取所有由0组成的行,并保留其余的行

我已经寻找了以前回答这个问题的问题,似乎 此问题与以下问题重复:

但我不理解任何答案。看起来重要的命令是:

a[~(a==0).all(1)]
但我根本不明白它是如何提取矩阵的。事实上,当我在代码中使用这一行时,它提取的是数组,而不是2d矩阵

我已经看过了
np.all()
, 但看起来这只是一个测试


有人能帮我一下吗。

这是一个有效的例子,也许不是最有效的:

import numpy as np
m=np.matrix([[1,2,3],[0,0,0], [4,5,6]])
m_nonzero_rows = m[[i for i, x in enumerate(m) if x.any()]]

在这里,您提取列表中具有索引号的行。您使用满足x.any()的行的索引号创建该列表,据我所知,如果行中的每个值都为0,则该列表将给出“False”。

与代码行
a[~(a==0)。所有(1)]
相关的主要问题是它适用于
numpy.array
,并且似乎您正在使用
numpy.matrix
,代码对其不太起作用。如果
a
numpy.matrix
,则使用
a[~(a==0).all(1.A1]

由于您是numpy新手,我将指出,通过将复杂的单行代码分解为单个步骤并打印中间结果,可以更好地理解这些代码。这通常是调试的第一步。对于
numpy.array
numpy.matrix
,我将对
a[~(a==0).all(1)]
行执行此操作

对于
numpy.array

In [1]: from numpy import *

In [2]: a = array([[4, 1, 1, 2, 0, 4],
                   [3, 4, 3, 1, 4, 4],
                   [1, 4, 3, 1, 0, 0],
                   [0, 4, 4, 0, 4, 3],
                   [0, 0, 0, 0, 0, 0]])

In [3]: print a==0
[[False False False False  True False]
 [False False False False False False]
 [False False False False  True  True]
 [ True False False  True False False]
 [ True  True  True  True  True  True]]

In [6]: print (a==0).all(1)
[False False False False  True]

In [7]: print ~(a==0).all(1)
[ True  True  True  True False]

In [8]: print a[~(a==0).all(1)]
[[4 1 1 2 0 4]
 [3 4 3 1 4 4]
 [1 4 3 1 0 0]
 [0 4 4 0 4 3]]
对于
numpy.matrix

In [1]: from numpy import *

In [2]: a = matrix([[4, 1, 1, 2, 0, 4],
                    [3, 4, 3, 1, 4, 4],
                    [1, 4, 3, 1, 0, 0],
                    [0, 4, 4, 0, 4, 3],
                    [0, 0, 0, 0, 0, 0]])

In [3]: print a==0
[[False False False False  True False]
 [False False False False False False]
 [False False False False  True  True]
 [ True False False  True False False]
 [ True  True  True  True  True  True]]


In [5]: print (a==0).all(1)
[[False]
 [False]
 [False]
 [False]
 [ True]]

In [6]: print (a==0).all(1).A1
[False False False False  True]

In [7]: print ~(a==0).all(1).A1
[ True  True  True  True False]

In [8]: print a[~(a==0).all(1).A1]
[[4 1 1 2 0 4]
 [3 4 3 1 4 4]
 [1 4 3 1 0 0]
 [0 4 4 0 4 3]]
[5]中
的输出显示了此操作不起作用的原因:
(a==0)。所有(1)
生成一个二维结果,该结果不能用于对行进行索引。因此,我在下一行中添加了
.A1
,将其转换为1D

对于数组和矩阵之间的差异,这是一个很好的答案。此外,我还要补充一点,一旦完全采用,使用
numpy.matrix
几乎没有任何好处。此外,由于大多数人在代码中使用
numpy.array
s来表示矩阵,因此他们通常将
numpy.array
描述为“矩阵”,从而造成术语上的混乱


最后,作为旁白,我将注意到上面的所有操作都是通过命令行完成的。IPython是这类工作的优秀工具。

从一行代码和示例开始。而不是在一行中完成,而是单独打印每个步骤。观察每一步的结果,找出每一步的结果。这是这里所有人都会做的,如果你自己做,你会更好地理解它。在这个特定问题的答案中没有代码。如果我将它们作为代码运行,则显示的行将给出一个错误。
a[~(a==0)。all(1)]
是我所指的代码行。当我在代码中运行该行时,它将使我成为一个数组。正如我所预测的那样。它不提取2D子矩阵。谢谢,让我测试一下!现在这是可行的。我仍然需要理解怎么做,但至少我有一些工作要做。我只是添加了m的定义,以防我们谈论的不是同一件事。我不是numpy专家,但我注意到矩阵和2d阵列之间的差异。如果我错了,请纠正我。我还添加了一些解释。@PietroSperoni:如果您不熟悉这些符号,这些一行代码很吸引人,但很难解析。所以你可以查一下,我要指出它不是真正的“双方括号”。这是一个内部对
[i代表i..]
,它是一个“列表理解”,是一个纯python的非numpy语句,位于方括号内,用于索引
m
。请注意,双方括号来自于在方括号内有一个列表供索引m[list\u of\u index]访问。正如您希望一次完成流程一样,我们在同一行中创建了列表。还请注意,for循环遍历枚举(m)中提取到i和x的所有项,其中i是索引,x是m在该索引中的内容(与执行m[i]时的值相同)。对不起,[#]中的是什么:这是我不知道的调试约定吗?这是从ipython控制台会话中直接剪切和粘贴的,其中[#]中的
是提示。基本上,您可以忽略它(尽管我建议您在这种类型的工作中研究ipython)。@tom10当您定义矩阵而不是数组时,这段代码的工作方式是否相同?在Python3中,如果我将a定义为a,则得到矩阵([[4,3,1,0]])matrix@PietroSperoni和@Mantxu:如果
a
np.matrix
,那么命令应该是
a[~(a==0).all(1).A1]
。但是,正如@hpaulj所说,最好使用
np.array
而不是
np.matrix
。(回想起来,我看到标题上写着“矩阵”,但对于numpy,人们通常仍然指
np.array
,因此不清楚问题实际上是关于哪种形式的。)@PietroSperoni:我编辑了我的答案,给出了完整的解释。可能太多了,但我希望能有所帮助。