NumPy で NaN を高速にチェックする 質問する

NumPy で NaN を高速にチェックする 質問する

np.nanNumPy 配列 でNaN ( ) の発生を確認する最も速い方法を探していますXnp.isnan(X)は問題外です。これは、X.shape潜在的に巨大な形状 のブール配列を構築するためです。

試してみましたnp.nan in Xが、 という理由でうまくいかないようですnp.nan != np.nan。これを高速かつメモリ効率よく実行する方法はありますか?

(「どれくらい巨大か」と尋ねる人に対して: わかりません。これはライブラリ コードの入力検証です。)

ベストアンサー1

レイの解決策は良い。しかし、私のマシンでは2.5倍ほど高速である。numpy.sum代わりにnumpy.min

In [13]: %timeit np.isnan(np.min(x))
1000 loops, best of 3: 244 us per loop

In [14]: %timeit np.isnan(np.sum(x))
10000 loops, best of 3: 97.3 us per loop

とは異なりminsumは分岐を必要としません。これは、最近のハードウェアでは非常にコストがかかる傾向があります。これが、 が高速である理由であると考えられますsum

編集上記のテストは、配列の真ん中に 1 つの NaN を配置して実行されました。

興味深いことに、minNaN がある場合の方がない場合よりも遅くなります。また、NaN が配列の先頭に近づくにつれて遅くなるようです。一方、sumのスループットは、NaN の有無や位置に関係なく一定であるようです。

In [40]: x = np.random.rand(100000)

In [41]: %timeit np.isnan(np.min(x))
10000 loops, best of 3: 153 us per loop

In [42]: %timeit np.isnan(np.sum(x))
10000 loops, best of 3: 95.9 us per loop

In [43]: x[50000] = np.nan

In [44]: %timeit np.isnan(np.min(x))
1000 loops, best of 3: 239 us per loop

In [45]: %timeit np.isnan(np.sum(x))
10000 loops, best of 3: 95.8 us per loop

In [46]: x[0] = np.nan

In [47]: %timeit np.isnan(np.min(x))
1000 loops, best of 3: 326 us per loop

In [48]: %timeit np.isnan(np.sum(x))
10000 loops, best of 3: 95.9 us per loop

おすすめ記事