首页 > 解决方案 > NumPy 屏蔽操作?

问题描述

假设有一个shapenp.float32矩阵。连同,我拥有另一个矩阵,类型,形状完全相同(元素可以1:1映射到)。例子:A(N, M)ABnp.boolAB

A =
[
    [0.1, 0.2, 0.3],
    [4.02, 123.4, 534.65],
    [2.32, 22.0, 754.01],
    [5.41, 23.1, 1245.5],
    [6.07, 0.65, 22.12],
]

B = 
[
    [True, False, True],
    [False, False, True],
    [True, True, False],
    [True, True, True],
    [True, False, True],
]

现在,我想执行np.max,np.min和on of np.argmax,但只考虑. 在 NumPy 中可以做这样的事情吗?该版本是微不足道的,但我想知道我是否可以获得一些多汁的 NumPy 速度。np.argminaxis=1AA[i,j]B[i,j] == Truefor-loop

A,Bnp.max(例如)的结果将是:

[ 0.3, 534.65, 22.0, 1245.5, 22.12 ]

我已经避免了ma,因为我听说计算变得非常慢,而且我觉得fill_value在这种情况下指定没有意义。我只想忽略这些数字。

此外,如果它对我来说很重要,N范围以千为单位,M范围以单位为单位。

标签: pythonnumpy

解决方案


这是屏蔽数组的教科书应用程序。但与往常一样,还有其他方法可以做到这一点。

import numpy as np

A = np.array([[ 0.1,    0.2,    0.3],
              [ 4.02, 123.4,  534.65],
              [ 2.32,  22.0,  754.01],
              [ 5.41,  23.1, 1245.5],
              [ 6.07,  0.65,   22.12]])

B = np.array([[ True, False,  True],
              [False, False,  True],
              [ True,  True, False],
              [ True,  True,  True],
              [ True,  False, True]])

nanmax

您可以将“无效”值转换为NaN(比如说),然后使用 NumPy 的特殊 NaN 忽略函数:

>>> A[~B] = np.nan  # <-- Note this mutates A
>>> np.nanmax(A, axis=1)
array([3.0000e-01, 5.3465e+02, 2.2000e+01, 1.2455e+03, 2.2120e+01])

问题是,虽然np.nanmaxnp.nanminnp.nanargmaxnp.nanargmin都存在,但许多函数没有非 NaN 孪生,所以你最终可能不得不想出别的东西。

ma

更不用说简单明了的掩码数组似乎很奇怪。请注意,面具(无论如何在我看来)是“向后”的。也就是说,True表示该值被“屏蔽”或无效,将被忽略。B因此必须用波浪号否定。然后你可以用掩码数组做你想做的事:

>>> X = np.ma.masked_array(A, mask=~B)  # <--- Note the tilde.
>>> np.max(X, axis=1)
masked_array(data=[0.3, 534.65, 22.0, 1245.5, 22.12],
             mask=[False, False, False, False, False],
       fill_value=1e+20)

推荐阅读