假设我们有一个矩阵:
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()
,但似乎也没有这样做。那里的任何解决方案都不需要循环或列表推导?非常感谢任何见解。感谢。
编辑:数据必须在处理后的相同列中。
答案 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])