2013-01-18 7 views
8

長時間リーダー、初めてのライター。*: 'numpy.ndarray'と 'numpy.float64'のサポートされていないオペランドタイプ

私はGoogleとスタックのオーバーフローで検索しましたが、この質問に対する一般的な回答は実際には見つかりませんでした。

numpy 1.6.2を使用して、Python 2.7.3で「*: 'numpy.ndarray'と 'numpy.float64'」というエラーが発生しました。

エラーはnumpy配列とnumpy floatを掛けたものですが、毎回発生しません。上記のように定義されたXと

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),-27)**40)), 
np.tan(np.abs(np.multiply(-31,41)))) 

のか、::

x = np.tan(1) # numpy.float64 
y = np.array([0,1,2,3]) # numpy.ndarray 
np.multiply(x,y) # works no problem 

それとも

x = np.tan(np.abs(np.multiply(-31,41))) # numpy.float64 
y = np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)) # numpy.ndarray 
np.multiply(x,y) # works no problem 

作業両方の問題の子供たちのために今すぐ

例えば

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)),x) 

の両方がエラーを生成します。両方を個別の変数に設定されたとき、それが働いたとして、私はランダム関数と数字は奇妙に思える知っているが、概念的には、これはまだ動作するはず

をNotImplemented。

どうしてですか?私はそれを一般的な意味でどのように修正できますか?

ありがとうございます! Jason

+0

私はあなたのコード内のバグをキャッチしていると思いますが、あなたはそれを報告したいこと貧弱な人々。レコードの場合、 'a'が' np.ndarray'で 'x'が' np.float64'ならば、 'x * a'と' a * x [...] 'の両方が動作しますが、' a * x'、 'a + x'、' a/x'または 'a-x'は行います。なぜ、 'a'の' __mul__'メソッドがそれを扱うことができない場合、 'x'の' __rmul__'は呼び出されません。なぜなら、ケースを処理する方法を知っているようだからです... – Jaime

+0

ありがとうございますそれを私のために吟味する。私はそれをnumpyの問題として報告しようとします。 これを回避する方法があると思いますか? – Jason

+0

'x'を' x [...] 'に置き換えるとうまくいきますが、厄介なハックです... – Jaime

答えて

7

ここで問題となるのは、NumPyがPython longの値をその配列に格納できないということです。これを行うとすぐに、配列のデータ型がobjectに切り替わります。 NumPyはもはや算術自体を行うことができないので、配列の算術演算は難しくなります。時々動作することができ、引数の順序を入れ替える奇妙な

>>> np.array(27**40) 
array(1797010299914431210413179829509605039731475627537851106401L, dtype=object) 
>>> np.array(27**40) * np.tan(1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for *: 'numpy.ndarray' and 'numpy.float64' 

、この第2のケースで

>>> np.tan(1) * np.array(27**40) 
2.7986777223711575e+57 

は、結果の型は、Python floatなく、numpyのアレイです。

修正がnumpyのアレイでlong値を作成しないし、代わりにfloat Sを使用することです:

>>> np.array(27.0**40) 
array(1.797010299914431e+57) 
>>> np.array(27.0**40) * np.tan(1) 
2.7986777223711575e+57 
>>> np.multiply(np.square(np.add(np.divide(np.zeros(10),42),(-27.0)**40)),np.tan(1)) 
array([ 5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114, 5.02925269e+114, 5.02925269e+114, 
     5.02925269e+114]) 

をあなたは、このようなエラーが出る行う場合には未来がある、まず最初に行うには、チェックすることです配列のdtypeが乗算されます。 NumPy値やPythonオブジェクトが含まれていますか?

+0

よろしくお願いします!私の配列変数(y = np.square(np.add(np.zeros(100)、42)、( - 27)** 40))私の質問で上で定義したように)タイプ 'オブジェクト'( 残念ながら私はそれをフロートとして強制することはできませんが、それはフロートとして始まり、途中のどこかに長くキャストされると考えています。 – Jason

+0

これは '(-27)** 40'の問題です。 NumPyはPythonの 'long'を直接扱うことができません。しかし、 'np.array'を使ってNumPy配列を別の型の別の配列に変換することができます。たとえば、 'np.array(np.array(27 ** 40)、dtype = np.float64)'は 'float64'型の配列を返します。 –

+0

はい私はint 27と40がコード内で生成されている場所を見つけ出し、浮動小数点としてキャストできました。レコードの場合、np.arangeはint32を生成します。ほとんどのnumpy関数はnp.onesとnp.zerosを含む浮動小数点数で動作します – Jason

-1

これはクイズですか?私はなぜその質問があまりにも難解であるのか理解していない...すべてがこの単純な事実にまでこだわる。我々はこれはバグある

>>> y.__mul__(x) 
1e+100 
>>> y.__rmul__(x) 
NotImplemented 

を持って

>>> x = 10**100 
>>> type(x) 
<type 'long'> 
>>> y = np.float64(1) 

を考えると

(または機能、私は知らない)それは、少なくともxのこれらの特定の値のために(y.__mul__(x) == y.__rmul__(x)する必要がありますので、およびy)。

のPython longnumpy.float64との乗算を処理する方法を知らない(しかし、これは正しいです。)

>>> x.__mul__(y) 
NotImplemented 
>>> x.__rmul__(y) 
NotImplemented 

だからy*xy.__mul__(x)に評価され、期待される結果を与えます。反対に、x*yy.__rmul__(x)(実装されていませんがバグです)よりx.__mul__(y)(実行されていない、OK)として最初に試されます。

すでに指摘したように、私たちは任意のオブジェクトのnd.arraysを持つことができ、すべてが明確になります。

編集

このバグは(おそらくnumpyの版で1.7。)修正されました:

>>> np.version.version 
'1.13.1' 
>>> x = 10**100 
>>> y = np.float64(1) 
>>> x.__mul__(y) 
NotImplemented 
>>> x.__rmul__(y) 
NotImplemented 
>>> y.__mul__(x) 
1e+100 
>>> y.__rmul__(x) 
1e+100 
>>> x*y 
1e+100 
>>> y*x 
1e+100 
+0

なぜこれがダウン表示されますか? – Worthy7

+0

@ Worthy7私の答えが下落した理由は分かりません:IMHO予期せぬ動作の原因となっているnumpyバグを特定しています。https://github.com/numpy/numpy/issues/2930#issuecomment-12445232で確認しました。そのnumpyの問題を読んだ後に私の答えを書いていませんでした。) –

関連する問題