numpyの - 仮面のアレイ上のより高速な演算?

何:

私はnumpyの配列を持っています:

import numpy as np
arr = np.random.rand(100)

私はその最大値を検索したい場合は、私が実行np.amax実行される155357私のマシンで時間秒を。

しかし、いくつかの理由から、私はその値の一部をマスクする必要があります。例えば、ただ一つのセルをマスクし、することができます:

import numpy.ma as ma
arr = ma.masked_array(arr, mask=[0]*99 + [1])

今、最高を見つけることが実行されている、はるかに遅い26574回秒。

これが唯一である17%なしマスキングアレイ上のこの操作の速度。

その他の動作は、例えば、あるsubtractaddmultiply彼らは上で動作するマスクされたアレイ上がすべての値、それだけで4%なしマスキングアレイ(15343/497663)と比較して速度の

私は、その使用numpyのかどうか、このようなマスクされた配列を操作するためのより高速な方法を探しています。

(私は本当の複数の次元を持つ配列であるデータ、および細胞の数百万人でこれを実行する必要があります)

hpaulj:

MaskedArrayベースnumpyののサブクラスですndarrayこれは、独自のコードをコンパイルしていません。見てnumpy/ma/の詳細、またはメインファイルのディレクトリ:

/usr/local/lib/python3.6/dist-packages/numpy/ma/core.py

マスクされた配列は、キー属性にあり、dataそしてmask、一つは、あなたが、同じサイズの他のブール配列を、それを作成するために使用されるデータ配列です。

だから、すべての操作を考慮に入れ、それら二つの配列を取らなければなりません。それは新しい計算するだけでなくdata、それはまた、新しいを計算していますmask

これは、いくつかのアプローチ(操作に応じて)を取ることができます。

  • 使用dataされます

  • 使用圧縮data-削除マスクされた値を含む新しい配列

  • 満たされた使用dataマスクされた値が置き換えられているところ、fillvalueまたはいくつかの無害な値(乗算を行う場合に加え、1をやったときに例えば0)。

マスクされた値は、0または全ての数は、もしあれば、差はスピード少ないます。

速度差だからあなたが見ることは驚くべきことではありません。起こって余分な計算がたくさんあります。ma.core.pyファイルには、このパッケージは第1の予備numpyの時代に開発された、とに組み込まれたと言うnumpyの日付にそれを維持するために変更が加えられているが周りの2005年、私はそれが大幅に改訂されたとは思いません。

ここのコードです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

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=291997&siteId=1