【问题标题】:Fastest way to mask a 4D Boolean numpy array屏蔽 4D 布尔 numpy 数组的最快方法
【发布时间】:2021-05-06 14:52:46
【问题描述】:

使用 2D 布尔掩码屏蔽 4D 布尔数组的最有效方法。

我尝试了两种方法:

A.将遮罩重塑为 4D 并遮罩

B.将倒置蒙版重塑为 4D 并乘以两个矩阵

import numpy as np
import time

I = 150
J = 2000
K = I
S = 25

matrix_to_mask = np.random.choice(a=[True, False], size=(I, J, K, S))
mask_2d = np.random.choice(a=[True, False], size=(I, S))

t = time.time()
matrix_to_mask[np.tile(mask_2d[:, np.newaxis, np.newaxis, :], (1, J, K, 1))] = False
print("Mask: " + str(time.time() - t)) # 2.77 sec

t = time.time()
a = matrix_to_mask * np.tile(np.invert(mask_2d)[:, np.newaxis, np.newaxis, :], (1, J, K, 1))
print("Product: " + str(time.time() - t)) # 1 sec

有没有其他方法可以加快蒙版速度?

谢谢

【问题讨论】:

    标签: python performance numpy boolean mask


    【解决方案1】:

    我会为此使用np.broadcast_to。广播会生成低维数组的“虚拟”副本。例如。该数组沿您指定的维度重复,但没有分配新的内存,它只会指向原始值。所以这更有效,因为它使用的内存更少,而且速度更快,因为它不花时间分配。

    t = time.time()
    mask_4d = np.broadcast_to(mask_2d, matrix_to_mask.shape)
    
    a = matrix_to_mask * mask_4d
    # matrix_to_mask[mask_4d] = False
    print("Broadcast: " + str(time.time() - t))
    

    所以:

    import numpy as np
    import time
    
    I = 150
    J = 1000
    K = I
    S = 25
    
    matrix_to_mask = np.random.choice(a=[True, False], size=(I, J, K, S))
    mask_2d = np.random.choice(a=[True, False], size=(I, S))
    
    t = time.time()
    matrix_to_mask[np.tile(mask_2d[:, np.newaxis, np.newaxis, :], (1, J, K, 1))] = False
    print("Mask: " + str(time.time() - t)) # 2.77 sec
    
    t = time.time()
    a = matrix_to_mask * np.tile(mask_2d[:, np.newaxis, np.newaxis, :], (1, J, K, 1))
    print("Product: " + str(time.time() - t)) # 1 sec
    
    t = time.time()
    mask_4d = np.broadcast_to(mask_2d, matrix_to_mask.shape)
    
    a = matrix_to_mask * mask_4d
    # matrix_to_mask[mask_4d] = False
    print("Broadcast: " + str(time.time() - t))
    

    面具:2.0803346633911133

    产品:0.8886129856109619

    广播:0.4950692653656006

    也就是说,我检查了获得的掩码和您使用np.tile(mask_2d[:, np.newaxis, np.newaxis, :], (1, J, K, 1)) 生成的掩码的值,但它们不对应,所以有些问题。也许检查您的方法是否确实产生了您想要的掩码,因为通常np.broadcast_to 完全符合您的要求,所以我认为这是正确的......

    【讨论】:

    • 看起来很有希望。但是,仅适用于维度 k = I 的特殊情况。例如,如果我将 k(轴 = 2)维度更改为 10,则 np.broarcast_to 不起作用。基本上,2d 蒙版是第一个和最后一个轴,而不是 4D 的最后两个轴。 np.broadcast_to 似乎不允许在 mask_2d 之间添加轴。
    • 要解决我上面的评论,在应用np.broadcast_to 之前必须进行重塑。 mask_4d 现在是:np.broadcast_to(mask_2d[:, np.newaxis, np.newaxis, :], matrix_to_mask.shape)。在我的机器中加起来最多 0.7 秒。速度还是不错的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多