私は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%なしマスキングアレイ上のこの操作の速度。
その他の動作は、例えば、あるsubtract
、add
とmultiply
。彼らは上で動作するマスクされたアレイ上がすべての値、それだけで4%なしマスキングアレイ(15343/497663)と比較して速度の
私は、その使用numpyのかどうか、このようなマスクされた配列を操作するためのより高速な方法を探しています。
(私は本当の複数の次元を持つ配列であるデータ、および細胞の数百万人でこれを実行する必要があります)
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