LoginSignup
1
1

More than 3 years have passed since last update.

[失敗談] ndarray に + 1 したら、意図せず dtype が変わってしまった

Posted at

前提

拙作の強化学習用ライブラリcpprbの開発の中で遭遇したバグ (issue)

強化学習のExperience Replay用にデータを一時保存しておくためのライブラリであり、そのデータの型はユーザーがコンストラクタで指定し、内部ではNumpyのndarrayとして保存していた。

バグ (失敗)

先日、(厳密には違うが)こんな感じのコードで ndarray に加算を行ったところ、意図せず dtype まで変わってしまい挙動がおかしくなってしまった。

バグ
import numpy as np

def create_buffer(shape,dtype):
    return np.zeros(shape=shape,dtype=dtype) + 1

create_buffer(1,np.bool) # array([1]) np.bool ではなくなってる!! np.int64

オペレータ + の代わりに、numpy.add を利用しても出力される型は変わってしまう。
(仮に出力先 out に一旦格納した元の変数を指定するとnumpy.core._exceptions.UFuncTypeError: Cannot cast ufunc 'add' output from dtype('int64') to dtype('bool') with casting rule 'same_kind' と怒られる。)

解決策

以下のように、計算した結果を要素毎に代入すると(あくまで型が変換可能な場合のみだが)元の型を維持した計算ができる。

修正
import numpy as np

def create_buffer(shape,dtype):
    a = np.zeros(shape=shape,dtype=dtype)
    a[:] = a + 1
    return a

create_buffer(1,np.bool) # array([True])

余談

別の目的があって、たまたま加算を実行しただけであって、加算自体には意味はない。
(boolの加算が...ということは、この記事の本題ではない。)

あくまで、ndarray にオブジェクトレベルの演算をしたら、意図せず型を変換されてしまったという失敗談。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1