2010-10-06 159 views
49

删除行我有一个数组看起来像这样的:在numpy的阵列

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]] 

注意,行已在最后一个零值。我想删除包含零的任何行,同时保留所有单元格中包含非零值的行。

但是每次填充时数组都会有不同数量的行,并且每次都将位于不同的行中。

我得到每行中非零元素与下面的代码行的数目:

NumNonzeroElementsInRows = (ANOVAInputMatrixValuesArray != 0).sum(1) 

对于上面的阵列,NumNonzeroElementsInRows包括:[5 4]

五个表明第0行中的所有可能值都是非零值,而第4行则表示第1行中的一个可能值为零。

因此,我试图使用以下几行代码来查找和删除包含零值的行。

for q in range(len(NumNonzeroElementsInRows)): 
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max(): 
     p.delete(ANOVAInputMatrixValuesArray, q, axis=0) 

但由于某些原因,该代码似乎并没有做任何事情,即使做了很多打印命令表明所有的变量似乎是正确的填充导致该代码。

必须有一些简单的方法来简单地“删除任何包含零值的行”。

任何人都可以告诉我要写什么代码来完成这个任务吗?

回答

4

这与您的原始方法类似,并会使用比unutbu's answer更少的空间,但我怀疑它会变慢。

>>> import numpy as np 
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]]) 
>>> p 
array([[ 1.5, 0. ], 
     [ 1.4, 1.5], 
     [ 1.6, 0. ], 
     [ 1.7, 1.8]]) 
>>> nz = (p == 0).sum(1) 
>>> q = p[nz == 0, :] 
>>> q 
array([[ 1.4, 1.5], 
     [ 1.7, 1.8]]) 

顺便说一句,你的行p.delete()不为我工作 - ndarray都不具备的一个.delete属性。

+8

简单一点:对[〜(P == 0).ANY(1)]或行更加明确:P [〜(P == 0).ANY(1),:] – user333700 2010-10-07 01:19:52

+0

@ user333700 - 这应该是一个答案 - 你一定会得到我的投票!在这种使用中,'any'比'sum'更清晰。 – mtrw 2010-10-07 01:26:31

12

这里有一个衬垫(是的,它类似于user333700的,却多了几分直白):

>>> import numpy as np 
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
       [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]) 
>>> print arr[arr.all(1)] 
array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875 , 0.53172222]]) 

顺便说一句,这种方法是很多的,比大矩阵蒙面阵列方法更快。对于2048 x 5的矩阵,这种方法快了大约1000倍。

顺便说一句,user333700的方法(来自他的评论)在我的测试中稍微快了一点,尽管它令我难以置信的原因为什么。

+3

“任何”可能会短路,只要检测到第一个真实情况,它就可以停止,而“全部”必须检查所有条件。所以,不是(在numpy中是“〜”),一般来说应该比所有的都快。 – user333700 2010-10-11 02:23:16

+3

@ user333700,它们都可以短路,只是为了不同的事情。在检测到的第一个真实情况下,任何短路都为真;在检测到的第一个错误情况下,“全部”短路为假。在这种情况下,短路应该是平局,但是在我看来,做多余的不应该让它慢下来。 – 2010-10-11 02:28:58

2

numpy提供了一个简单的函数来完成同样的事情: 假设你有一个被屏蔽的数组'a',调用numpy.ma.compress_rows(a)将删除包含被屏蔽值的行。 我想这是更快的方式...

96

从数组中删除行和列的最简单方法是numpy.delete方法。

假设我有以下数组x

x = array([[1,2,3], 
     [4,5,6], 
     [7,8,9]]) 

要删除的第一行,这样做:

x = numpy.delete(x, (0), axis=0) 

要删除第三列,这样做:

x = numpy.delete(x,(2), axis=1) 

所以你可以找到其中有0的行的索引,把它们放在一个列表或元组中并将其作为函数的第二个参数传递。

+0

谢谢!我有同样的问题,我不明白为什么简单地调用'numpy.delete(x,index)'不起作用。 – Antimony 2015-11-20 22:59:22

+3

请注意,[numpy delete()文档](https://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html)指出“通常最好使用布尔掩码”,因为返回一个新数组 - 在该链接下提供一个示例 – arturomp 2016-10-27 03:42:07

0

我可能为时太晚回答这个问题,但想分享我的意见,以利于社区。对于这个例子,让我打电话给你的矩阵'ANOVA',我假设你只是试图从这个矩阵中删除行,只在第5列中使用0。

indx = [] 
for i in range(len(ANOVA)): 
    if int(ANOVA[i,4]) == int(0): 
     indx.append(i) 

ANOVA = [x for x in ANOVA if not x in indx]