Numpy,如何使用布尔切片获得子矩阵

pin*_*eng 5 python arrays numpy matrix

我有一个问题:如何通过布尔切片获得子矩阵像子数组?

例如:

    a2 = np.array(np.arange(30).reshape(5, 6))
    a2[a2[:, 1] > 10]
Run Code Online (Sandbox Code Playgroud)

会给我:

    array([[12, 13, 14, 15, 16, 17],
           [18, 19, 20, 21, 22, 23],
           [24, 25, 26, 27, 28, 29]])
Run Code Online (Sandbox Code Playgroud)

但:

    m2 = np.mat(np.arange(30).reshape(5, 6))
    m2[m2[:, 1] > 10]
Run Code Online (Sandbox Code Playgroud)

会给我:

    matrix([[12, 18, 24]])
Run Code Online (Sandbox Code Playgroud)

为什么输出不同?如何从矩阵得到与数组相同的结果?

谢谢!

sap*_*api 4

您遇到的问题归结为矩阵返回的操作始终返回二维数组。

当您在第一个数组上构建掩码时,您会得到:

In [24]: a2[:,1] > 10
Out[24]: array([False, False,  True,  True,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这是一个一维数组。

当你对矩阵做同样的事情时,你会得到:

In [25]: m2[:,1] > 10
Out[25]: 
matrix([[False],
        [False],
        [ True],
        [ True],
        [ True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

换句话说,你有一个 nx1 数组,而不是长度为 n 的数组。


numpy 中的索引操作方式有所不同,具体取决于您是使用一维数组还是 n 维数组进行索引。

在第一种情况下,numpy 会将长度为 n 的数组视为行索引,因此您将得到预期的结果:

In [28]: a2[a2[:,1] > 10]
Out[28]: 
array([[12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29]])
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,因为你有一个二维索引数组,所以 numpy 有足够的信息来提取行和列,因此它只从匹配列(第一个列)中获取内容:

In [29]: m2[m2[:,1] > 10]
Out[29]: matrix([[12, 18, 24]])
Run Code Online (Sandbox Code Playgroud)

要回答您的问题:您可以通过将掩码转换为数组并抓取第一列来提取长度为 n 的初始数组来获得此行为:

In [32]: m2[np.array(m2[:,1] > 10)[:,0]]
Out[32]: 
matrix([[12, 13, 14, 15, 16, 17],
        [18, 19, 20, 21, 22, 23],
        [24, 25, 26, 27, 28, 29]])
Run Code Online (Sandbox Code Playgroud)

或者,您可以先进行转换,得到与之前相同的结果:

In [34]: np.array(m2)[:,1] > 10
Out[34]: array([False, False,  True,  True,  True], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

现在,这两个修复都需要矩阵和数组之间的转换,这可能非常难看。

我要问自己的问题是为什么你希望使用矩阵,但又期望数组的行为。适合您工作的工具实际上可能是数组,而不是矩阵。