Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python NumPy-在屏蔽阵列上更快的操作?_Python_Arrays_Numpy - Fatal编程技术网

Python NumPy-在屏蔽阵列上更快的操作?

Python NumPy-在屏蔽阵列上更快的操作?,python,arrays,numpy,Python,Arrays,Numpy,我有一个numpy阵列: 将numpy导入为np arr=np.rand.rand(100) 如果我想找到它的最大值,我运行np.amax,它在我的机器上每秒运行155357次 然而,由于某些原因,我不得不掩盖它的一些价值观。例如,让我们仅屏蔽一个单元格: 将numpy.ma导入为ma arr=ma.masked_数组(arr,mask=[0]*99+[1]) 现在,找到最大值要慢得多,每秒运行26574次 这仅为非屏蔽阵列上此操作速度的17% 例如,其他操作包括减法、加法和乘法。虽然在屏蔽

我有一个numpy阵列:

将numpy导入为np
arr=np.rand.rand(100)
如果我想找到它的最大值,我运行
np.amax
,它在我的机器上每秒运行155357次

然而,由于某些原因,我不得不掩盖它的一些价值观。例如,让我们仅屏蔽一个单元格:

将numpy.ma导入为ma
arr=ma.masked_数组(arr,mask=[0]*99+[1])
现在,找到最大值要慢得多,每秒运行26574次

这仅为非屏蔽阵列上此操作速度的17%

例如,其他操作包括
减法
加法
乘法
。虽然在屏蔽阵列上,它们对所有值进行操作,但与无屏蔽阵列(15343/497663)相比,速度仅为4%

我正在寻找一种更快的方法来操作像这样的屏蔽阵列,不管它是否使用numpy


(我需要在真实数据上运行它,它是多维数组和数百万个单元格)

MaskedArray
是基本numpy
ndarray
的子类。它没有自己的编译代码。有关详细信息,请查看
numpy/ma/
目录或主文件:

/usr/local/lib/python3.6/dist-packages/numpy/ma/core.py
蒙版数组必须具有键属性,
data
mask
,一个是用于创建它的数据数组,另一个是相同大小的布尔数组

因此,所有操作都必须考虑这两个数组。它不仅计算新的
数据
,还必须计算新的
掩码

它可以采取几种方法(取决于操作):

  • 按原样使用
    数据

  • 使用压缩的
    数据
    -删除屏蔽值的新数组

  • 使用填充的
    数据
    ,其中被屏蔽的值被替换为
    填充值
    或一些无害的值(例如,进行加法时为0,进行乘法时为1)

屏蔽值的数量(0或全部)对速度的影响很小(如果有的话)

因此,你看到的速度差异并不令人惊讶。还有很多额外的计算。
ma.core.py
文件称,该软件包最初是在numpy之前开发的,并于2005年左右并入
numpy
。虽然有一些变化使它保持最新,但我认为它并没有得到明显的修改

以下是
np.ma.max
方法的代码:

def max(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue):

    kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims}

    _mask = self._mask
    newmask = _check_mask_axis(_mask, axis, **kwargs)
    if fill_value is None:
        fill_value = maximum_fill_value(self)
    # No explicit output
    if out is None:
        result = self.filled(fill_value).max(
            axis=axis, out=out, **kwargs).view(type(self))
        if result.ndim:
            # Set the mask
            result.__setmask__(newmask)
            # Get rid of Infs
            if newmask.ndim:
                np.copyto(result, result.fill_value, where=newmask)
        elif newmask:
            result = masked
        return result
    # Explicit output
    ....
关键步骤是

fill_value = maximum_fill_value(self)  # depends on dtype
self.filled(fill_value).max(
            axis=axis, out=out, **kwargs).view(type(self))
您可以使用
filled
进行实验,以查看数组中发生了什么

In [40]: arr = np.arange(10.)                                                                                        
In [41]: arr                                                                                                         
Out[41]: array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [42]: Marr = np.ma.masked_array(arr, mask=[0]*9 + [1])                                                            
In [43]: Marr                                                                                                        
Out[43]: 
masked_array(data=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, --],
             mask=[False, False, False, False, False, False, False, False,
                   False,  True],
       fill_value=1e+20)
In [44]: np.ma.maximum_fill_value(Marr)                                                                              
Out[44]: -inf
In [45]: Marr.filled()                                                                                               
Out[45]: 
array([0.e+00, 1.e+00, 2.e+00, 3.e+00, 4.e+00, 5.e+00, 6.e+00, 7.e+00,
       8.e+00, 1.e+20])
In [46]: Marr.filled(_44)                                                                                            
Out[46]: array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8., -inf])
In [47]: arr.max()                                                                                                   
Out[47]: 9.0
In [48]: Marr.max()                                                                                                  
Out[48]: 8.0