web-dev-qa-db-ja.com

NumPy配列からすべてのゼロ要素を削除するにはどうすればよいですか?

ランク1がありますnumpy.array箱ひげ図を作成したい。ただし、配列内のゼロに等しいすべての値を除外します。現在、配列をループしてこれを解決し、ゼロでない場合は値を新しい配列にコピーしました。しかし、配列は86 000 000の値で構成されており、これを複数回実行する必要があるため、これには多くの忍耐が必要です。

これを行うよりインテリジェントな方法はありますか?

24
ruben baetens

これは、マスクされた配列を使用する場合であり、配列の形状を保持し、すべての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
21
Andrea Zonca

NumPy配列aの場合、次を使用できます

a[a != 0]

ゼロに等しくない値を抽出します。

53
Sven Marnach

簡単なコード行で、すべての「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]
6
David Guest

このような場合、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)

enter image description here

3
eat

ブール配列でインデックスを付けることができます。 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
2
jpp

ここで説明したさまざまなアプローチの実行時間を比較することにしました。私は自分のライブラリ simple_benchmark をこれに使用しました。

array[array != 0]を使用したブールインデックスは、最速(かつ最短)のソリューションのようです。

enter image description here

小さい配列の場合、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()
0
MSeifert