如何在numpy中迭代时删除行

时间:2015-03-09 17:10:16

标签: python numpy matrix linear-algebra

如何在numpy中迭代时删除行,就像Java那样:

Iterator < Message > itMsg = messages.iterator();
while (itMsg.hasNext()) {
    Message m = itMsg.next();
    if (m != null) {
        itMsg.remove();
        continue;
    }
}

这是我的伪代码。迭代时删除条目全为0和1的行。

#! /usr/bin/env python
import numpy as np

M = np.array(
    [
        [0, 1 ,0 ,0],
        [0, 0, 1, 0],
        [0, 0, 0, 0], #remove this row whose entries are all 0
        [1, 1, 1, 1]  #remove this row whose entries are all 1
    ])


it = np.nditer(M, order="K", op_flags=['readwrite'])
while not it.finished :
    row = it.next()     #how to get a row?
    sumRow = np.sum(row)
    if sumRow==4 or sumRow==0 : #remove rows whose entries are all 0 and 1 as well
        #M = np.delete(M, row, axis =0)
        it.remove_axis(i)  #how to get i?

1 个答案:

答案 0 :(得分:1)

编写好的numpy代码需要您以矢量化的方式进行思考。并非每个问题都具有良好的矢量化,但对于那些问题,您可以非常轻松地编写干净且快速的代码。在这种情况下,我们可以决定要删除/保留哪些行,然后使用它来索引您的数组:

>>> M
array([[0, 1, 0, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 0],
       [1, 1, 1, 1]])
>>> M[~((M == 0).all(1) | (M == 1).all(1))]
array([[0, 1, 0, 0],
       [0, 0, 1, 0]])

我们可以逐步将M与某些东西进行比较,以制作一个布尔数组:

>>> M == 0
array([[ True, False,  True,  True],
       [ True,  True, False,  True],
       [ True,  True,  True,  True],
       [False, False, False, False]], dtype=bool)

我们可以使用all查看行或列是否全部为真:

>>> (M == 0).all(1)
array([False, False,  True, False], dtype=bool)

我们可以使用|执行or操作:

>>> (M == 0).all(1) | (M == 1).all(1)
array([False, False,  True,  True], dtype=bool)

我们可以用它来选择行:

>>> M[(M == 0).all(1) | (M == 1).all(1)]
array([[0, 0, 0, 0],
       [1, 1, 1, 1]])

但由于这些是我们想要丢弃的行,我们可以使用~(NOT)来翻转FalseTrue

>>> M[~((M == 0).all(1) | (M == 1).all(1))]
array([[0, 1, 0, 0],
       [0, 0, 1, 0]])

如果我们希望保留并且不是1或全部0,我们只需要更改我们正在运行的轴于:

>>> M
array([[1, 1, 0, 1],
       [1, 0, 1, 1],
       [1, 0, 0, 1],
       [1, 1, 1, 1]])
>>> M[:, ~((M == 0).all(axis=0) | (M == 1).all(axis=0))]
array([[1, 0],
       [0, 1],
       [0, 0],
       [1, 1]])