如何从numpy矩阵中排除元素

时间:2015-07-05 18:21:39

标签: python numpy

假设我们有一个矩阵:

mat = np.random.randn(5,5)

array([[-1.3979852 , -0.37711369, -1.99509723, -0.6151796 , -0.78780951],
       [ 0.12491113,  0.90526669, -0.18217331,  1.1252506 , -0.31782889],
       [-3.5933008 , -0.17981343,  0.91469733, -0.59719805,  0.12728085],
       [ 0.6906646 ,  0.2316733 , -0.2804641 ,  1.39864598, -0.09113139],
       [-0.38012856, -1.7230821 , -0.5779237 ,  0.30610451, -1.30015299]])

假设我们还有一个索引数组:

idx = np.array([0,4,3,1,3])

虽然我们可以使用以下方法从矩阵中提取元素:

mat[idx, range(len(idx))]
array([-1.3979852 , -1.7230821 , -0.2804641 ,  1.1252506 , -0.09113139])

我想知道的是我们如何使用索引从矩阵中排除元素,即如何获得以下结果:

array([[0.12491113 , -0.37711369, -1.99509723, -0.6151796 , -0.78780951],
       [-3.5933008 ,  0.90526669, -0.18217331, -0.59719805, -0.31782889],
       [0.6906646  , -0.17981343,  0.91469733,  1.39864598,  0.12728085],
       [-0.38012856,  0.2316733 , -0.5779237 ,  0.30610451, -1.30015299]])

认为这就像做mat[-idx, range(len(idx))]一样简单,但这不起作用。我也尝试了np.delete(),但似乎也没有这样做。那里的任何解决方案都不需要循环或列表推导?非常感谢任何见解。感谢。

编辑:数据必须在处理后的相同列中。

1 个答案:

答案 0 :(得分:1)

当你说'删除'不起作用时,你的意思是什么?它有什么作用?这可能是诊断性的。

让我们先看一下有效的选择:

In [484]: mat=np.arange(25).reshape(5,5) # I like this better than random

In [485]: mat[idx,range(5)]
Out[485]: array([ 0, 21, 17,  8, 19])

这也可用于文件的扁平版本:

In [486]: mat.flat[idx*5+np.arange(5)]
Out[486]: array([ 0, 21, 17,  8, 19])

现在尝试使用默认的平面delete

In [487]: np.delete(mat,idx*5+np.arange(5)).reshape(5,4)
Out[487]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  9],
       [10, 11, 12, 13],
       [14, 15, 16, 18],
       [20, 22, 23, 24]])

delete不是一个现场操作员;它返回一个新矩阵。如果指定轴,delete将删除整行或列,而不是选定的项目。

mat[-idx, range(len(idx))]无法正常工作,因为负面索引已经具有意义 - count from the end

这个delete最终会做布尔索引,因此:

In [498]: mat1=mat.ravel()
In [499]: idx1=idx*5+np.arange(5)
In [500]: ii=np.ones(mat1.shape, bool)
In [501]: ii[idx1]=False
In [502]: mat1[ii]
Out[502]: 
array([ 1,  3,  4,  5,  6,  7,  8,  9, 10, 12, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24])

即使您从每行中删除了不同数量的项目,这种索引/删除仍然有效。当然,在这种情况下,你不能指望将矩阵重新塑造成矩形矩阵。

通常,当处理不同行的不同索引时,操作最终会作用于矩阵的平面或平面版本。处理1d数组时,“不规则”操作通常比使用2d更有意义。

仔细查看您的示例,我看到当您删除某个项目时,您将其他列值向上移动以填补空白。在我的版本中,我沿着行移动了值。让我们用F命令试试这个。

In [523]: mat2=mat.flatten('F')
In [524]: np.delete(mat2,idx2).reshape(5,4).T
Out[524]: 
array([[ 5,  1,  2,  3,  4],
       [10,  6,  7, 13,  9],
       [15, 11, 12, 18, 14],
       [20, 16, 22, 23, 24]])

我从每列中删除了一个值:

In [525]: mat2[idx2]
Out[525]: array([ 0, 21, 17,  8, 19])