【问题标题】:Delete columns from matrix according to its index根据其索引从矩阵中删除列
【发布时间】:2016-05-16 18:42:25
【问题描述】:

我有一个二维矩阵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 列。

【问题讨论】:

  • 很高兴分享您已经尝试过的内容。请记住,SO 不是代码编写服务。
  • Condition i%2==0 将删除第 0 列以及第 2 列和第 4 列。这是因为 Python(和许多其他计算机语言)中的索引从 0 开始。

标签: python arrays list matrix


【解决方案1】:

如果子列表的长度相同,您可以在列表理解中使用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]])
>>> 

【讨论】:

    【解决方案2】:

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

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

    现在,您可以创建一个result 二维数组,该数组的行数与matrixK 相同,而len(columnFlag) 的列数少于matrixK

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

    【讨论】:

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

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

      【讨论】:

        【解决方案4】:

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

        # 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]))
        

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

        【讨论】:

          猜你喜欢
          • 2021-11-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-08
          相关资源
          最近更新 更多