在numpy中最简单的方法来对矩阵的索引向量进行排除,每一行中不包含一个索引?

时间:2018-12-27 20:00:19

标签: python numpy

假设我在M[0,:]处有一个具有以下内容的numpy ndarray M:

[2, 3.9, 7, 9, 0, 1, 8.1, 3.2]

,并且在运行时给我一个整数k,介于0和7之间。我想生成由该行中除k列以外的所有项组成的向量。 (例如:如果k = 3,则所需向量为[2,3.9,7,0,1,8.1,3.2])

有一种简单的方法吗?

如果我有一个索引k的向量,M的每一行一个,代表我要从行中排除的列,那该怎么办?

除了弄乱结果矩阵的非矢量循环之外,我有点迷茫:

nrows = M.shape[0]
result = np.zeros(nrows,M.shape[1]-1))
for irow in xrange(nrows):
    result[irow,:k[irow]] = M[irow,:k[irow]]   # content before the split point
    result[irow,k[irow]:] = M[irow,k[irow]+1:] # content after the split point

2 个答案:

答案 0 :(得分:3)

一种方法是使用masking/boolean-indexing-

mask = np.ones(M.shape,dtype=bool)
mask[np.arange(len(k)),k] = 0
out = M[mask].reshape(len(M),-1)

Alternativley,我们可以使用broadcasting来获取mask-

np.not_equal.outer(k,np.arange(M.shape[1]))
# or k[:,None]!=np.arange(M.shape[1])

因此,给我们提供了一个单线/紧凑版本-

out = M[k[:,None]!=np.arange(M.shape[1])].reshape(len(M),-1)

要在每行中排除多个,请为第一种方法编辑高级索引部分-

def exclude_multiple(M,*klist):
    k = np.stack(klist).T
    mask = np.ones(M.shape,dtype=bool)
    mask[np.arange(len(k))[:,None],k] = 0
    out = M[mask].reshape(len(M),-1)
    return out

样品运行-

In [185]: M = np.arange(40).reshape(4,10)

In [186]: exclude_multiple(M,[1,3,2,0],[4,5,8,1])
Out[186]: 
array([[ 0,  2,  3,  5,  6,  7,  8,  9],
       [10, 11, 12, 14, 16, 17, 18, 19],
       [20, 21, 23, 24, 25, 26, 27, 29],
       [32, 33, 34, 35, 36, 37, 38, 39]])

答案 1 :(得分:1)

改进@Divakar的答案,将其扩展为每行零个或多个排除的索引:

def excluding(A, *klist):
    """ 
    excludes column k from each row of A, for each k in klist 
    (make sure the index vectors have no common elements)
    """
    mask = np.ones(A.shape,dtype=bool)
    for k in klist:
        mask[np.arange(len(k)),k] = 0
    return A[mask].reshape(len(A),-1)

测试:

M = np.arange(40).reshape(4,10)
excluding(M,[1,3,2,0],[4,5,8,1])

返回

array([[ 0,  2,  3,  5,  6,  7,  8,  9],
       [10, 11, 12, 14, 16, 17, 18, 19],
       [20, 21, 23, 24, 25, 26, 27, 29],
       [32, 33, 34, 35, 36, 37, 38, 39]])