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