【问题标题】:Numpy filter matrix based on column基于列的numpy过滤矩阵
【发布时间】:2021-12-12 09:00:07
【问题描述】:

我有一个矩阵,每行有几个不同的值:

arr1 = np.array([[1,2,3,4,5,6,7,8,9],[10,11,12,13,14,15,16,17,18],[19,20,21,22,23,24,25,26,27]])
arr2 = np.array([["A"],["B"],["C"]])

这会产生以下矩阵:

array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18],
       [19, 20, 21, 22, 23, 24, 25, 26, 27]])

array([['A'],
       ['B'],
       ['C']])

A 代表前 3 列,B 代表接下来的 3 列,C 代表最后 3 列。所以我想要的结果是:

array([[1,2,3],
       [13,14,15],
       [25,26,27]])

我正在考虑将 arr2 转换为掩码数组,但我什至不确定如何执行此操作。如果是 1darray,我可以这样做:

arr[0,1,2]

但对于 2darray,我什至不知道如何像这样屏蔽。我试过这个并得到错误:

arr[[0,1,2],[3,4,5],[6,7,8]]

最好的方法是什么?

谢谢。

【问题讨论】:

    标签: python arrays numpy matrix


    【解决方案1】:

    您可以使用“高级索引”,通过坐标数组索引目标数组。

    rows = np.array([[0,0,0],[1,1,1],[2,2,2]])
    cols = np.array([[0,1,2],[3,4,5],[6,7,8]])
    
    arr1[rows, cols]
    >>> array([[ 1,  2,  3],
              [13, 14, 15],
              [25, 26, 27]])
    

    你可以做一些类似的功能

    def diagonal(arr, step):
        rows = np.array([[x]*step for x in range(step)])
        cols = np.array([[y for y in range(x, x+step)] for x in range(0, step**2, step)])
        return arr[rows, cols]
    
    diagonal(arr1, 3)
    >>> array([[ 1,  2,  3],
              [13, 14, 15],
              [25, 26, 27]])
    

    参考:https://numpy.org/devdocs/user/basics.indexing.html

    【讨论】:

    • 我知道这是很久以前的事了,但我认为这是最接近的可行方法。 Rows 似乎很好,但 cols 需要更灵活。实际上它可能是 A、B、A、C、B、...
    • 但我想我大概可以弄清楚如何从 ABC 数组中获取并将它们转换为 [0,1,2]、[3,4,5] 或 [6,7, 8]。谢谢
    【解决方案2】:

    如果您要固定 arr1 的形状,如上图(3,9) 所示,则可以使用如下单行代码完成:

    arr2  = np.array([arr1[0][0:3],arr1[1][3:6],arr1[2][6:9]])
    

    输出如下:

    [[ 1  2  3]
     [13 14 15]
     [25 26 27]]
    

    【讨论】:

      【解决方案3】:

      您可以使用string.ascii_uppercase 来索引字母表中的索引。并将 arr1 重塑 3 块:

      from string import ascii_uppercase
      reshaped = np.reshape(arr1, (len(arr1), -1, 3))
      reshaped[np.arange(len(arr1)), np.vectorize(ascii_uppercase.index)(arr2).ravel()]
      

      或者直接将A映射到0等等...

      reshaped = np.reshape(arr1, (len(arr1), -1, 3))
      reshaped[np.arange(len(arr1)), np.vectorize(['A', 'B', 'C'].index)(arr2).ravel()]
      

      两个输出:

      array([[ 1,  2,  3],
             [13, 14, 15],
             [25, 26, 27]])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-19
        • 1970-01-01
        • 2021-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多