141

入力に数値以外の値が少なくとも 1 つ含まれているかどうかを検出する関数を作成する必要があります。数値以外の値が見つかった場合は、エラーが発生します (計算は数値のみを返す必要があるため)。入力配列の次元数は事前にわかりません。関数は、ndim に関係なく正しい値を与える必要があります。さらに複雑なことに、入力は単一の float であったりnumpy.float64、0 次元配列のような変わったものであったりします。

これを解決する明白な方法は、再帰関数を記述して、配列内のすべての反復可能なオブジェクトを、非イテラーベが見つかるまで反復することです。numpy.isnan()すべての反復不可能なオブジェクトに関数を適用します。少なくとも 1 つの数値以外の値が見つかった場合、関数はすぐに False を返します。それ以外の場合、反復可能オブジェクトのすべての値が数値の場合、最終的に True が返されます。

それは問題なく動作しますが、かなり遅いので、NumPyにはもっと良い方法があると思います。より高速でより派手な代替手段は何ですか?

これが私のモックアップです:

def contains_nan( myarray ):
    """
    @param myarray : An n-dimensional array or a single float
    @type myarray : numpy.ndarray, numpy.array, float
    @returns: bool
    Returns true if myarray is numeric or only contains numeric values.
    Returns false if at least one non-numeric value exists
    Not-A-Number is given by the numpy.isnan() function.
    """
    return True
4

5 に答える 5

245

これは反復よりも高速で、形状に関係なく機能します。

numpy.isnan(myarray).any()

編集:30倍高速:

import timeit
s = 'import numpy;a = numpy.arange(10000.).reshape((100,100));a[10,10]=numpy.nan'
ms = [
    'numpy.isnan(a).any()',
    'any(numpy.isnan(x) for x in a.flatten())']
for m in ms:
    print "  %.2f s" % timeit.Timer(m, s).timeit(1000), m

結果:

  0.11 s numpy.isnan(a).any()
  3.75 s any(numpy.isnan(x) for x in a.flatten())

おまけ: 配列以外の NumPy タイプでも問題なく動作します:

>>> a = numpy.float64(42.)
>>> numpy.isnan(a).any()
False
>>> a = numpy.float64(numpy.nan)
>>> numpy.isnan(a).any()
True
于 2009-05-27T00:55:50.407 に答える
3

numpy 1.3 または svn を使用すると、これを行うことができます

In [1]: a = arange(10000.).reshape(100,100)

In [3]: isnan(a.max())
Out[3]: False

In [4]: a[50,50] = nan

In [5]: isnan(a.max())
Out[5]: True

In [6]: timeit isnan(a.max())
10000 loops, best of 3: 66.3 µs per loop

比較におけるナンの扱いは、以前のバージョンでは一貫していませんでした。

于 2009-08-25T00:04:43.780 に答える