为什么使用mask = None或mask = 0创建一个蒙版的numpy数组这么慢

MSe*_*ert 5 python performance numpy

今天我分析了一个函数,我发现了一个(至少对我而言)奇怪的瓶颈:使用mask=None或创建一个蒙版数组,或者mask=0用全零来初始化一个蒙版,但形状与data非常慢:

>>> import numpy as np
>>> data = np.ones((100, 100, 100))

>>> %timeit ma_array = np.ma.array(data, mask=None, copy=False)
1 loop, best of 3: 803 ms per loop

>>> %timeit ma_array = np.ma.array(data, mask=0, copy=False)
1 loop, best of 3: 807 ms per loop
Run Code Online (Sandbox Code Playgroud)

另一方面,手工使用mask=False或创建面膜要快得多:

>>> %timeit ma_array = np.ma.array(data, mask=False, copy=False)
1000 loops, best of 3: 438 µs per loop

>>> %timeit ma_array = np.ma.array(data, mask=np.zeros(data.shape, dtype=bool), copy=False)
1000 loops, best of 3: 453 µs per loop
Run Code Online (Sandbox Code Playgroud)

为什么给予None0慢近2000倍Falsenp.zeros(data.shape)作为mask参数?鉴于函数docs只说它:

必须可转换为与数据形状相同的布尔数组.True表示屏蔽(即无效)数据.

我在Windows 10上使用python 3.5,numpy 1.11.0

use*_*ica 5

mask=FalseNumPy 1.11.0源代码中是特殊情况:

if mask is True and mdtype == MaskType:
    mask = np.ones(_data.shape, dtype=mdtype)
elif mask is False and mdtype == MaskType:
    mask = np.zeros(_data.shape, dtype=mdtype)
Run Code Online (Sandbox Code Playgroud)

mask=0mask=None采用慢速路径,制作一个0维遮罩数组,然后np.resize调整其大小。