根据索引从矩阵中删除列

时间:2016-05-16 18:42:26

标签: python arrays list matrix

我有一个二维矩阵matrixK。例如,它可能类似于

matrixK = [[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]]

我需要删除矩阵的某些列,并且需要根据依赖于索引作为列的模式来选择这些列。 换句话说,

for i in range(number_of_columns)
    if (i satisfy a certain condtion):
        column[i] needs to be deleted.

并且作为最终结果,我需要获得相同的初始matrixK,剥夺了满足条件的列。什么是最好的pythonic方式呢?

举一个例子,参考上面定义的matrixK作为例子,让我们考虑一下

for i in range(5):
       if (i%2==0):
           column[i] needs to be deleted

应删除第2列和第4列。

4 个答案:

答案 0 :(得分:2)

如果子列表的长度相同,您可以在列表推导中使用zip()函数,如下所示:

>>> zip(*[j for i, j in enumerate(zip(*matrixK)) if i%2 != 0])
[(1, 3), (6, 8), (11, 13)]

或者您可以使用布尔索引numpy数组:

>>> arr = np.array(matrixK)
>>> arr[:,np.arange(arr.shape[1])%2 != 0]
array([[ 1,  3],
       [ 6,  8],
       [11, 13]])
>>> 

答案 1 :(得分:1)

您可以使用columnFlag数组来标记需要删除的列。

columnFlag = {}
for column in range(number_of_columns):
    if(satisfiesCondition(column)):
        columnFlag.add(column)

现在,您可以创建一个result二维数组,其行数与matrixKlen(columnFlag)列的行数相同,小于matrixK

将元素从matrixK复制到result,仅用于columnFlag以外的列,并返回result数组。

答案 2 :(得分:1)

 >>> matrixK[:] = map(lambda y : list(filter(lambda x: y.index(x)%2 != 0, y)), matrixK)
 >>> matrixK
 [[1, 3], [6, 8], [11, 13]]

您可以根据实际需要更改lambda filter函数内的条件

答案 3 :(得分:0)

这可以通过两种不同的方式完成,具体取决于您是否需要在原始矩阵中就地删除列,或者只需将其替换为新的列。每种方式的一个例子如下所示 请注意,两者都不要求矩阵的每一行都具有相同的长度。

# in-place removal of column in matrix

matrixK = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]

for row in matrixK:
    for i in reversed(range(len(row))):
        if i % 2 == 0:
           del row[i:i+1]

print('matrixK after: {}'.format(matrixK))

或者:

# removal of columns in matrix by recreating it

matrixK = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]

matrixK = [[row[i] for i in range(len(row)) if i % 2] for row in matrixK]

print('matrixK after: {}'.format(matrixK))

两个输出:

matrixK after: [[1, 3], [6, 8], [11, 13]]

更多信息

为了完全公开,请注意还有另一种方法可以执行列删除,这些方法涉及使用内置zip()函数,这非常快。

代码不像其他两个代码那样可读,只有当矩阵的每一行长度相同时才有效 - 但它比上面的两行快。

matrixK = zip(*[row for i, row in enumerate(zip(*matrixK)) if i % 2])

产生:

matrixK after: [(1, 3), (6, 8), (11, 13)]

每行都是tuple而不是list。如果这是一个问题,可以使用以下方法将它们转换为子列表:

matrixK = map(list, zip(*[row for i, row in enumerate(zip(*matrixK)) if i % 2]))

这确实会减慢速度,但它仍然比前两种方法快一些。