今回は numpy の関数の一つである empty 関数の基本的な使い方について解説いたします。
空の配列を生成したいという場合にこの関数を利用することが多いと思いますので、忘れてしまわないようにわかりやすく解説いたします。
empty関数とは
empty 関数は要素が未初期化の空の配列を生成する関数です。
生成する配列は、 numpy 形式の ndarray です。
未初期化とは簡単に変数が宣言されているが、明示的に値が設定されていない状況を指します。
しかし、値が設定されていない空の配列といっても各要素には確保したメモリに入っていた値がそのままランダムに割り当てられています。
作業場は確保したけど掃除はしていないので、そこにあったものがそのままあるよってことですね。
この関数の利点は値の初期化というお掃除とセッティングをしないので、その分ほかの関数より高速に配列を用意してあげることができるという点です。
0とか1で初期化する必要がないのであればこの関数を使うのが良いというわけですね。
簡単な empty 関数の使い方

はじめに、手っ取り早く使い方を知りたいという方のために、 empty 関数の最も簡単な使い方をご紹介いたします。
使い方は以下のように生成したい配列の形状を指定するだけです。
サンプルコード :
1 2 3 4 5 6 7 |
import numpy as np #要素数5の1次元のnumpy配列を作成 a = np.empty(5) #要素数2×4の2次元のnumpy配列を作成 b = np.empty((2,4)) |
生成する配列のデータ型を指定する場合は以下のようにします。
サンプルコード :
1 2 3 4 |
import numpy as np #int型のnumpy配列を生成 c = np.empty((2,4),int) |
empty 関数の各パラメータおよび戻り値について
それでは各パラメータおよび戻り値に関して詳しく確認していきます。
まずは記載方法です。
ndarray = empty(shape、 dtype = float、 order = ‘C’)
記載例 :
ndarray = np.empty ( ( 2, 4 ) , float , ‘C’)
ndarray = np.empty ( ( 2, 4 ) ) #必須の引数のみ
区分 | 項目名 | 説明 |
引数 : 必須 | shape | 生成する配列の形を指定します。 |
引数 : 任意 | dtype | 要素のデータ型を指定します。省略可能で、デフォルトは float 型です。 |
引数 : 任意 | order | データの保存方法を指定します。省略可能で、デフォルトは ‘C’ です。(’C’ か ‘F’ から選択) |
戻り値 | 配列 ( ndarray ) | shape で指定した形状の未初期化のからの配列を生成します。 |
引数
shape (配列の形状)
shape の 指定例 : np.empty ( ( 2, 4 ) )
shape は、empty 関数における唯一必須の引数で、配列の形状を指定します。
指定方法はタプルのデータ型で指定します。(1次元配列ならint型でも問題ないです。)
1次元配列を指定したい場合は empty(5) (もしくは empty((5,)) ),
2次元配列なら empty((2,4))といった具合で指定します。
配列の形状は numpy 配列であれば、numpy のs hape 関数で取得できるので empty(nparray.shape) といった形で指定したりすると便利です。
ただこれには類似の empty_like という関数があるのでそちらを使う方が良いかもしれません。
dtype(データ型)
dtypeの指定例 : np.empty ( ( 2, 4 ) , int )
dtypeは作成される配列の要素のデータ型を指定します。
デフォルト引数であり、初期値には float が設定されています。
そのため、特に指定しなくてもよい引数です。
intにて配列を生成したい場合は “int” と記載してあげるだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#指定なし(float) np.empty ( ( 2, 4 ) ) """ array([[4.68141862e-310, 1.58101007e-322, 6.77127876e-043, 7.56215079e-067], [3.93610279e-062, 5.69998526e-038, 3.85778140e-057, 1.03878559e-013]]) """ #======================================================================== #intを指定 np.empty ( ( 2, 4 ) , int ) """ array([[ 94752967654144, 32, 3976172072849113087, 3617625477359022693], [3688502190842197556, 4049691966624378980, 3762818198976933990, 4412750542886809344]]) """ |
order(格納方法)
orderの指定例 : np.empty ( ( 2, 4 ) , int , ‘F’)
orderはデータの格納方法を指定します。
‘C’ か ‘F’ から選択するデフォルト引数です。初期値は ‘C’ です。
Cの意味としてはC言語方式という意味で行優先に格納する方式です。
Fの意味としてはFortran方式という意味で反対に列優先に格納する方式です。
あまり意識するような場面がないので、基本的には指定することはない引数かなと思います。
因みに実際にどんな違いがあるかどうかは empty 関数の利用ではランダムな値なのでよくわからないのですが、 numpy 配列を作成するときにも同様に order を指定できるので、それで確認することができます。
order の確認 :
1 2 3 4 5 6 7 8 9 10 11 |
import numpy as np #C言語方式(デフォルト) order = 'C' array_c = np.arange(10).reshape((2, 5), order='C') print('□□□C言語方式□□□') print(array_c ) # Fortran形式 order = 'F' array_f = np.arange(10).reshape((2, 5), order='F') print('□□□Fortan形式□□□') print(array_f ) |
結果 :
□□□C言語方式□□□
[[0 1 2 3 4][5 6 7 8 9]]
□□□Fortan形式□□□
[[0 2 4 6 8][1 3 5 7 9]]
戻り値
ndarray = np.empty ( ( 2, 4 ) , int , ‘F’)
empty 関数の戻り値は ndarray という numpy 配列です。
ndarrayとは簡単に numpy で利用できる多次元リストのことです。
以下のようにして記述いたします。
ndarray = np.array( [1, 3, 5] )
通常は上記のようにして初期化して用意しますが、empty 関数を使えば初期化せずにほしい形状の ndarray を用意できるというわけです。
1 2 3 4 5 6 7 |
import numpy as np #初期化あり ndarray = np.array([1, 3, 5]) #初期化なし emparray = np.empty(3) |
【使用例】配列の初期化が必要ない場合
配列の初期化を必要としない場合というのは大抵は、後で別の値を代入するからわざわざ初期化する必要がなく、値を格納できる箱だけほしいという場合ですね。
そこに値を入れる必要がないのにわざわざ np.zeros や np.ones のように0や1で初期化するのはもったいないので np.empty で配列を用意しようということです。
例えば、ある配列を数倍にして別の配列に格納したいという場合、以下のようにして書くことができます。
サンプルコード :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import numpy as np X = np.array([[1,2],[3,7],[4,5]]) # 3×2 の行列 a = 3 result = np.empty(X.shape,int) i = 0 #行のインデックス for row in X: j = 0 #列のインデックス for num in row: result[i][j] = num * a j += 1 i += 1 print("before :") print(X) print("after : ") print(result) |
余談 : 他の関数と実行速度を比較してみる
何回もメリットとして np.zeros や np.ones といった関数より高速であることを記載してきましたが、じゃあ実際どれくらい早いのかというのを %timeit コマンドで確認してみましょう。
■np.zerosの場合
1 |
%timeit np.zeros(10000) |
The slowest run took 485.29 times longer than the fastest.
This could mean that an intermediate result is being cached.
100000 loops, best of 5: 2.6 µs per loop
■np.emptyの場合
1 |
%timeit np.empty(10000) |
The slowest run took 29.48 times longer than the fastest.
This could mean that an intermediate result is being cached.
1000000 loops, best of 5: 837 ns per loop
■結果
np.zeros : 2.6μ秒
np.empty : 0.837μ秒
大体3倍くらいには早いことがわかります。
ただし、要素 1 万 の配列の生成で1ミリ秒にも満たない時間しか変わらないとも言えます。
まぁこういうところのケアが結構大きく変わってきたりもしますし、なるべく empty 関数を使ってあげるといいかもしれません。
今回はここまでです。
お疲れ様でした。
コメント