Abstract
np.zeros
とnp.zeros_like
はdtypeに関する振る舞いが異なるので気を付けようという話
環境
- Windows 10
- Python 3.10.9
- numpy 1.24.2
import numpy as np
落とし穴
np.zeros
とnp.zeros_like
は次のように相互に書き換えられるとよく紹介されます。
>>> x = np.arange(0, 5, 0.2)
>>> x
array([0. , 0.2, 0.4, 0.6, 0.8, 1. , 1.2, 1.4, 1.6, 1.8, 2. , 2.2, 2.4,
2.6, 2.8, 3. , 3.2, 3.4, 3.6, 3.8, 4. , 4.2, 4.4, 4.6, 4.8])
>>> a = np.zeros(x.shape)
>>> a
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.])
# こう書いても同じだよ!
>>> b = np.zeros_like(x)
>>> b
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0.])
次の例では、同じ結果になっていません。
>>> x = np.arange(5)
>>> a = np.zeros(x.shape)
>>> a
array([0., 0., 0., 0., 0.])
>>> b = np.zeros_like(x)
>>> b
array([0, 0, 0, 0, 0])
# dtypeが違う!!
>>> x.dtype, a.dtype, b.dtype
(dtype('int32'), dtype('float64'), dtype('int32'))
# dtypeを指定してあげないと同じ結果にならない
>>> b = np.zeros_like(x, dtype = np.float64)
>>> b
array([0., 0., 0., 0., 0.])
つまり同じ結果になるのはx.dtype == np.float64
の時だけです。
np.zeros
はdtype
を引数で指定しない場合はnp.float64
になります。
一方でnp.zeros_like
は受け取ったnumpy配列のdtype
を引き継ぐようになっています。
そのため、単にshape
が同じ配列を作りたいという時は、意識しておいてdtype
を指定しましょう。