特定の値の関数を作成するときのpython / numpyのAttributeError

Source python numpy scipy

「スーパーガウス」関数を生成してプロットするPythonコードを次のように書いています。
def supergaussian(x, A, mu, sigma, offset, N=8):
    """Supergaussian function, amplitude A, centroid mu, st dev sigma, exponent N, with constant offset"""
    return A * (1/(2**(1+1/N)*sigma*2*scipy.special.gamma(1+1/N))) * numpy.exp(-numpy.absolute(numpy.power(x-mu,N))/(2*sigma**N)) + offset

init_x = numpy.arange(-100,100,1.0)
init_y = supergaussian(init_x, 1, 0, 25, 0, N=12)

次のコードは、それをプロットするだけです。理解できない理由により、このコードは、Nにデフォルト値の8を使用する場合、またはNの値が13までの場合に正常に機能します。Nが14以上の場合、関数は次のエラーメッセージでクラッシュします。
AttributeError: 'float' object has no attribute 'exp'

関数定義の戻り行。何か案は?その行で.expを使用しているのはnumpy.expだけなので、エラーメッセージは、numpyがfloatとして解釈されていることを示しているようですが、Nの値が大きい場合のみです...

numpy1.7.1とscipy0.12.0でpython3.3.2を実行しています
推奨答え
このエラーは、いくつかの厄介なdtypeの奇妙さによるものです。内部でどのように機能するかは正確にはわかりませんが、何らかの理由で2*25**14がNumpyのデータ型の処理方法の変更をトリガーします。
>>> type(np.max(-numpy.absolute(numpy.power(init_x-0,13)))/(2*25**13))
<type 'numpy.float64'>
>>> type(np.max(-numpy.absolute(numpy.power(init_x-0,14)))/(2*25**14))
<type 'float'>

13では、Numpyのfloat64タイプを使用しますが、14では、どういうわけか通常のfloatに戻ります。これが、AttributeErrorが発生する理由です。通常のPythonフロートには、numpyufuncメソッドであるexpメソッドがありません。 (このエラーは、名前numpyがfloatとして解釈されたことが原因ではありません。これらのnumpy-internalエラーは、属性を持たないオブジェクトが何であるかを教えてくれないため、役に立たない場合があります。)

ただし、これは、数値2*25**Nが通常のPythonの長さであり、numpyデータ型の値ではないためにのみ発生します。次のように、その値をnumpydtypeで事前にラップすることで修正できます。
def supergaussian(x, A, mu, sigma, offset, N=8):
    """Supergaussian function, amplitude A, centroid mu, st dev sigma, exponent N, with constant offset"""
    denom = np.float64(2*sigma**N)
    return A * (1/(2**(1+1/N)*sigma*2*scipy.special.gamma(1+1/N))) * numpy.exp(-numpy.absolute(numpy.power(x-mu,N))/denom) + offset

これで、大きな値に対して正常に機能します。

変換の失敗は、2*25**14が大きすぎてnumpyint64に収まらないことが原因のようです。これは私にはバグのように見えます。int64に対して大きすぎる場合は、float64にフォールバックするか、エラーを発生させる必要があります。サイレントにプレーンフロートにフォールバックするのではありません。 numpy trackerに関連するバグがあるようですが、少し異なります。 numpyトラッカーやメーリングリストで問題を提起することをお勧めします。

関連記事

グループ内の列を並べ替えてデータフレームを再配置する
clojurehoneysqlのwhere句の作成
matplotlibプロットの上に目盛りラベルを表示する方法は?
リスト内包表記なしでリスト内の要素を置き換える、スライスする、または[]を使用する
ジェネレーター関数の値をスキップする