删除numpy数组中的行


88

我有一个可能看起来像这样的数组:

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行中的所有可能值都不为零,而四个表示第1行中的可能值之一为零。

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

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

但是由于某种原因,即使执行大量打印命令表明所有变量似乎都正确填充了代码,该代码似乎也无能为力。

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

谁能告诉我要编写什么代码来完成此任务?

Answers:


162

从数组中删除行和列的最简单方法是该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的行的索引,将它们放在列表或元组中,并将其作为函数的第二个参数传递。


谢谢!我遇到了同样的问题,我不知道为什么简单地打电话numpy.delete(x, index)不起作用。

6
请注意,numpy delete()文档指出“通常最好使用布尔掩码”,因为会返回一个新数组-在该链接下提供了一个示例
arturomp 16-10-27

1
@arturomp,但面罩无损。调用delete()会消耗时间/内存吗?
内森

13

这是一个衬板(是的,它类似于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
“ any”会短路,一旦检测到第一个真实情况,它就会停止,而“ all”则必须检查所有情况。因此,通常(比numpy中的“〜”要大)要快。
约瑟夫,

4
@ user333700,它们两者都可能短路,只是对不同的事物。any在检测到的第一个真实情况下短路至真实;all在检测到的第一个错误情况下短路到错误。在这种情况下,短路应该是引人注意的,但我认为这样做不应该使速度变慢。
贾斯汀·皮

5

这与您的原始方法类似,并且将比unutbu的答案使用更少的空间,但我怀疑它会更慢。

>>> 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 [〜(p == 0).any(1)]或更明确地显示行:p [〜(p == 0).any(1),:]
约瑟夫

2

numpy提供了一个简单的函数来执行完全相同的操作:假设您有一个掩码数组'a',调用numpy.ma.compress_rows(a)将删除包含掩码值的行。我想这样会更快


1
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[np.where(arr != 0.)])

-1

我可能回答这个问题为时已晚,但想分享我的意见,以造福社区。对于此示例,让我将矩阵称为“ 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]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.