ランク1がありますnumpy.array
箱ひげ図を作成したい。ただし、配列内のゼロに等しいすべての値を除外します。現在、配列をループしてこれを解決し、ゼロでない場合は値を新しい配列にコピーしました。しかし、配列は86 000 000の値で構成されており、これを複数回実行する必要があるため、これには多くの忍耐が必要です。
これを行うよりインテリジェントな方法はありますか?
これは、マスクされた配列を使用する場合であり、配列の形状を保持し、すべてのnumpy関数とmatplotlib関数によって自動的に認識されます。
X = np.random.randn(1e3, 5)
X[np.abs(X)< .1]= 0 # some zeros
X = np.ma.masked_equal(X,0)
plt.boxplot(X) #masked values are not plotted
#other functionalities of masked arrays
X.compressed() # get normal array with masked values removed
X.mask # get a boolean array of the mask
X.mean() # it automatically discards masked values
NumPy配列a
の場合、次を使用できます
a[a != 0]
ゼロに等しくない値を抽出します。
簡単なコード行で、すべての「0」値を除外する配列を取得できます。
np.argwhere(*array*)
例:
import numpy as np
array = [0, 1, 0, 3, 4, 5, 0]
array2 = np.argwhere(array)
print array2
[1, 3, 4, 5]
このような場合、NaN
を単に使用することをお勧めします。この場合、一部の値を無視しますが、手順をできるだけ意味のある統計に保ちたいです。そう
In []: X= randn(1e3, 5)
In []: X[abs(X)< .1]= NaN
In []: isnan(X).sum(0)
Out[: array([82, 84, 71, 81, 73])
In []: boxplot(X)
ブール配列でインデックスを付けることができます。 NumPy配列の場合A
:
res = A[A != 0]
上記のように ブール配列インデックス を使用できます、bool
型変換、 np.nonzero
、または np.where
。パフォーマンスのベンチマークは次のとおりです。
# Python 3.7, NumPy 1.14.3
np.random.seed(0)
A = np.random.randint(0, 5, 10**8)
%timeit A[A != 0] # 768 ms
%timeit A[A.astype(bool)] # 781 ms
%timeit A[np.nonzero(A)] # 1.49 s
%timeit A[np.where(A)] # 1.58 s
ここで説明したさまざまなアプローチの実行時間を比較することにしました。私は自分のライブラリ simple_benchmark
をこれに使用しました。
array[array != 0]
を使用したブールインデックスは、最速(かつ最短)のソリューションのようです。
小さい配列の場合、MaskedArrayアプローチは他のアプローチと比較して非常に低速ですが、ブールインデックスアプローチと同じくらい高速です。ただし、適度なサイズの配列の場合、それらの間に大きな違いはありません。
これが私が使ったコードです:
from simple_benchmark import BenchmarkBuilder
import numpy as np
bench = BenchmarkBuilder()
@bench.add_function()
def boolean_indexing(arr):
return arr[arr != 0]
@bench.add_function()
def integer_indexing_nonzero(arr):
return arr[np.nonzero(arr)]
@bench.add_function()
def integer_indexing_where(arr):
return arr[np.where(arr != 0)]
@bench.add_function()
def masked_array(arr):
return np.ma.masked_equal(arr, 0)
@bench.add_arguments('array size')
def argument_provider():
for exp in range(3, 25):
size = 2**exp
arr = np.random.random(size)
arr[arr < 0.1] = 0 # add some zeros
yield size, arr
r = bench.run()
r.plot()