『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

未初期化配列

numpy.empty()

numpy.empty() は要素が初期化されていない空の配列 (未初期化配列) を返します。

numpy.empty(shape, dtype=float, order='C')

3 × 3 の未初期化配列を生成してみます。

# NUMPY_EMPTY

# In[1]

import numpy as np

# 未初期化配列を生成
arr = np.empty((3, 3))

print(arr)
# [[1.91290538e+092 1.43587367e+214 2.55172530e+151]
#  [2.29249727e+170 1.97626258e-323 1.06099790e-313]
#  [3.50108086e-310 2.14701544e+289 1.56705074e+294]]

各要素には不規則な値が格納されています。empty (空) とは全ての要素が 0 であるという意味ではありません。ほとんどの配列生成関数は確保したメモリブロック (連続メモリ) の値を再設定 (初期化) しますが、numpy.empty() はそのような書き込みを行なわずに、現在メモリに格納されている値をそのまま配列要素とします。
 
一般に、numpy.empty() は要素を書き込むための空箱として使うので、初期化の二度手間を省いて処理速度を向上させるというメリットがあります。np.empty(10**5) , np.zeros(10**5), np.ones(10**5) で、それぞれ 10 万要素をもつ配列を生成して処理速度を比較してみます。

# In[2]

%timeit np.empty(10**5)
# 1.61 µs ± 31.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)


# In[3]

%timeit np.zeros(10**5)
# 50.2 µs ± 259 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)


# In[4]

%timeit np.ones(10**5)
# 48.1 µs ± 1.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

実行結果を見ても明らかなように、np.empty() は np.zeros() や np.ones() に比べて、配列生成速度が圧倒的に速いです。

numpy.empty_like()

numpy.empty_like() は、受け取った配列と同じサイズの未初期化配列を返します。

empty_like(prototype, dtype=None, order='K', subok=True)

たとえば、prototype に 3 × 3 の配列を渡すと 4 × 4 の未初期化配列を返します。

# NUMPY_EMPTY_LIKE

# In[1]

import numpy as np

# 4×4の配列xを生成
x = np.ones((3, 3))

# xと同じサイズの未初期化配列を生成
y = np.empty_like(x)

print(y)
# [[1.91290538e+092 1.43587367e+214 2.55172530e+151]
#  [2.29249727e+170 1.97626258e-323 1.06099790e-313]
#  [3.50108086e-310 2.14701544e+289 1.56705074e+294]]

コメント

  1. HNaio より:

    numpy.empty( ) の処理時間の計測を、私の PC で試した結果は以下の通りでした。

    %timeit np.empty(10**5) … 727 ns
    %timeit np.zeros(10**5) … 31.9 μs
    %timeit np.ones(10**5) … 46.6 μs

    圧倒的に np.empty( ) が速いのですが、本文の記事では np.empty( ) と np.zeros( ) が同程度となっているのが少し納得できませんでした。お手数ですが再度ご確認していただけるとありがたいです。

    • あとりえこばと より:

      私の PC で Jupyte Notebook を起動して再確認したところ、以下のような実行結果になりました。
      %timeit np.empty(10**5) … 1.61 µs
      %timeit np.zeros(10**5) … 52 µs
      %timeit np.ones(10**5) … 47.3 µs

      Google Colab でも試してみました。
      %timeit np.empty(10**5) … 2.81 µs
      %timeit np.zeros(10**5) … 37.8 µs
      %timeit np.ones(10**5) … 52.3 µs
      おっしゃるように、np.empty() のほうが圧倒的に速かったです。そもそも、記事本文に「 np.empty() は処理速度を向上させるというメリットがある」と書いたのに、np.zeros() と同程度の速度だったらおかしいですよね。本当に申し訳ないです。直ちに記事も訂正させていただきます。m(_ _)m