NumPyのempty関数で空の配列(未初期化配列)を生成する方法

np.empty関数は、要素が初期化されていない空の配列を生成する関数です。ただし、「空」と言っても、厳密にはメモリに格納されている値がランダムに割り当てられます。

要素が欠損値np.nanの配列を生成したい場合は、np.full関数を使います。こちらに関しては、『numpy.full関数で全要素が指定の値の初期化配列を生成する方法』の中で解説しているのでご確認ください。

さて、NumPyには、初期化配列を生成するための様々な関数が用意されていますが、その中でもnp.empty関数は、要素を変換せずにメモリからそのまま取り出すので高速であるという特徴があります。

このページでは、このnp.empty関数の使い方を解説していきます。

なお、同じような関数にnp.empty_like関数というものがあります。こちらは、既にある配列の属性(形状やデータ型、メモリレイアウト、サブクラス)を引き継いだ上で、要素が空(未初期化)の配列を生成します。このページでは、この関数についても解説します。

それでは見ていきましょう。

目次

1. np.empty関数の使い方

1.1. 書式

まずは、基本的な書き方を確認しましょう。

numpy.empty関数

書き方:

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

パラメーター:

shape: 整数(int型) または 整数のタプル
配列のshapeを指定する。
dtype: データ型(オプション)
要素のデータ型を指定する。デフォルト値はnp.float64。
order: ’C’ か ‘F’ から選択(オプション)
多次元データのメモリレイアウトを C言語方式(行優先)か Fortran方式(列優先)から選択する。デフォルトは ‘C’。

戻り値: 

out: 配列(ndarray)
指定の形状・データ型で要素が空(未初期化)の配列

一緒に確認したい関数:

  • zeros: 要素が0の初期化配列を生成
  • ones: 要素が1の初期化配列を生成
  • full: 要素が任意の値の初期化配列を生成
  • empty_like: 既存の配列から要素が空の(未初期化の)配列を生成 

1.2. サンプルコード

それでは、実際のコードで使い方を確認していきましょう。

1次元配列の生成

np.empty関数は、引数に任意のshapeを渡すだけで、未初期化配列を生成します。要素の値は、空いているメモリに格納されているランダムな値になります。

以下のコードでは長さ5の1次元配列を生成しています。

In [1]:
import numpy as np
#  長さ5で要素の値が初期化されていない1次元配列を生成
arr1 = np.empty(5)
#  こちらの書き方でも可
arr1 = np.empty((5,))

print(arr1)
[-1.28822975e-231 -1.28822975e-231  1.78837779e-202  4.72057675e-284
  1.18500631e-303]

多次元配列の生成

多次元配列を生成する場合は、shapeは必ずタプルで指定します。

In [2]:
#   2次元配列を生成
arr2 = np.empty((2, 2))
print('2次元配列\n', arr2, '\n')

#  3次元配列を生成
arr3 = np.empty((2, 2, 3))
print('3次元配列\n', arr3)
2次元配列
 [[1.43279037e-322 1.28822975e-231]
 [1.28822975e-231 1.08694442e-322]] 

3次元配列
 [[[-1.28822975e-231 -1.28822975e-231  5.92878775e-323]
  [ 0.00000000e+000  0.00000000e+000  0.00000000e+000]]

 [[ 0.00000000e+000  0.00000000e+000  0.00000000e+000]
  [ 0.00000000e+000  0.00000000e+000  0.00000000e+000]]]

なお、指定の形状が小さい場合は、ランダムな値ではなく0が入ることもあります。

In [3]:
#  shapeによっては0埋めになる
np.empty((2, 1))
Out[3]:
array([[0.],
       [0.]])

以上がnp.empty関数の基本的な使い方です。

デフォルトのデータ型やメモリレイアウトを変更したい場合にオプション引数 dtype= order= を使います。

データ型を変更

np.empty関数で生成する配列のデータ型は、デフォルトではfloat64ですが、オプション引数 dtype= で別のデータ型を指定することができます。

なお、データ型については『NumPyのdtypeの一覧と確認・指定・変更方法』で詳しく解説しています。

それでは、以下のコードをご覧ください。

In [4]:
'''  データ型を指定  '''
#  int型
arr4 = np.empty((2, 2), dtype=int)
print('int型で生成\n', arr4, '\n')
#  complex型
arr5 = np.empty((2, 2), dtype=complex)
print('complex型で生成\n', arr5)
int型で生成
 [[0 0]
 [0 0]] 

complex型で生成
 [[0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j]]

ビット数も指定可能です。

In [5]:
'''  ビット数も指定可能  '''
#  int32
arr6 = np.empty((2, 2), dtype=np.int32)
print('int32型\n', arr6, '\n')

#  float32
arr7 = np.empty((2, 3), dtype='float32')
print('float32型\n', arr7)
int32型
 [[0 0]
 [0 0]] 

float32型
 [[0.000000e+00 2.524355e-29 0.000000e+00]
 [2.524355e-29 1.681558e-44 0.000000e+00]]

メモリレイアウトの変更

オプション引数 order= では、メモリレイアウトを変更することができます。PythonのデフォルトのメモリレイアウトはC言語方式(行優先)ですが、別にFortran方式(列優先)を選択することができます。

それぞれ以下のように異なるレイアウトで格納されます。

In [6]:
'''  C言語方式(デフォルト)  '''
arr_c = np.arange(6).reshape((2, 3), order='C')
print('C言語方式\n', arr_c, '\n')

'''  Fortran方式  '''
arr_f = np.arange(6).reshape((2, 3), order='F')
print('Fortan方式\n', arr_f)
C言語方式
 [[0 1 2]
 [3 4 5]] 

Fortan方式
 [[0 2 4]
 [1 3 5]]

np.empty関数でも、同じようにメモリレイアウトを指定することができます。

In [7]:
#  C言語方式(デフォルト)
arr8 = np.empty((3, 4), order='C')
print('C言語方式\n', arr8.flags, '\n')

#  Fortran方式
arr9 = np.empty((3, 4), order='F')
print('Fortran方式\n', arr9.flags)
C言語方式
   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
 

Fortran方式
   C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

2. np.empty_like関数の使い方

np.empty_like関数は、既存の配列の属性(形状、データ型、メモリレイアウト、サブクラス)を引き継ぎ、その要素は非初期化の値の配列を生成する関数です。

ここで一緒に確認していきましょう。

2.1. 書式

基本的な書き方は次の通りです。

numpy.empty_like関数

書き方:

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

パラメータ:

a: array_like オブジェクト(リストや配列など)
生成する配列のshapeを指定する。
dtype: データ型(オプション)
データ型を上書きしたい場合に指定する。
order: ’C’ ‘F’ ‘A’ ‘K’ のいずれか(オプション)
メモリ内での配列の並び方を上書きしたい場合に指定します。’C’はC言語方式です。’F’はFortran形式です。’A’は、元の配列がFortranであればFortran形式で、そうでなければ’C’言語方式で並べます。’K’は、元の配列のメモリ内の並び方に近いものを選択します。デフォルトは’K’です。
subok: ブール値(オプション)
Trueでは、新しく生成される配列は、元の配列のサブクラス(マスクされた配列かマトリックス)を引き継ぎます。Falseでは、通常の配列として生成されます。デフォルトはTrueです。
shape: 整数 または 整数のシーケンス(オプション)
新しく生成する配列のshapeを上書きする。order=’K’で次元数を変えない場合はorderは元の配列を引き継ぐ。それ以外の場合はorder=’C’になる。

戻り値: 

元の配列 aと同じ形状、データ型、メモリレイアウト、サブクラスで、要素が未初期化の新しい配列

一緒に確認したい関数:

  • zeros_like: 既存の配列から要素が0の初期化配列を生成
  • ones_like既存の配列から要素が1の初期化配列を生成
  • full_like既存の配列から任意の値の初期化配列を生成
  • empty: 要素が空(未初期化)の配列を生成

2.2. サンプルコード

それでは、サンプルコードを見ていきましょう。

繰り返しですが、np.empty_like関数は、既存の配列の形状・データ型・メモリレイアウト・サブクラスを引き継いで、要素のみが未初期化の新しい配列を生成します。

In [1]:
import numpy as np

#  shape(3, 4)、dtype=int64、order='C'の配列を生成
l = range(25)
arr1= np.array(l, dtype=int, order='C').reshape(5, 5)
print('arr1:\n ',arr1, '\n')

#  arr1を元にarr2を生成
arr2 = np.empty_like(arr1)
print('arr2:\n', arr2, '\n')
print('shape:\n', arr2.shape, '\n')
print('dtype:\n', arr2.dtype)
arr1:
  [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]] 

arr2:
 [[5764607523034234880 5764607523034234880     140396048482319
      140396048536944     140396075181200]
 [    140396075191224     140396048537840     140396048537896
      140396049745488     140396073688624]
 [    140396048543216     140396075368624     140396075171248
      140396075368688     140396075368752]
 [    140396075368816     140396048538736     140396074518992
      140396075191296     140396075368880]
 [    140396048548224     140396048546096     140396048546416
      140396048546800     140396033882744]] 

shape:
 (5, 5) 

dtype:
 int64

もし、基本的には元の配列と同じ属性を引き継ぎたいが、一部を変更したい時はオプション引数で指定してやる必要があります。

その際は、データ型やメモリレイアウト、サブクラス、形状を指定することができます。それぞれ見ていきましょう。

データ型の変更

データ型の変更は、オプション引数 dtype= で指定します。

以下のコードでは、データ型がint型の配列を第一引数に引き渡していますが、第二引数で型をcomplex型に上書きしています。

In [2]:
#  dtypeをcomplex型で上書き
arr3 = np.empty_like(arr1, dtype=complex)
print(arr3)
print('shape: ', arr3.shape)
print('dtype: ', arr3.dtype)
[[ 0.e+000+0.j  0.e+000+0.j  0.e+000+0.j  0.e+000+0.j]
 [ 0.e+000+0.j -0.e+000-0.j  4.e-323+0.j  0.e+000+0.j]
 [ 0.e+000+0.j  0.e+000+0.j  0.e+000+0.j  0.e+000+0.j]]
shape:  (3, 4)
dtype:  complex128

要素が指定の型になっていますね。

メモリレイアウトの変更

メモリレイアウトの変更は、オプション引数 order= で行います。以下のコードでは、Fortran方式に上書きしています。

In [3]:
#  orderをFortran方式で上書き
arr4 = np.empty_like(arr1, order='F')
print(arr4)
print('shape: ', arr4.shape)
print('dtype: ', arr4.dtype)
[[                   0                    0                    0
                     0]
 [                   0                    0                    0
                     0]
 [                   0 -9223372036854775808                    0
                     0]]
shape:  (3, 4)
dtype:  int64

サブクラスの変更

NumPyの配列(ndarray)にはサブクラスとして、マトリックス(matrix)とマスクされた配列(MakedArray)があります。元となる配列が、これらのサブクラスである場合、デフォルトでは、そのサブクラスを受け継ぎます。

一方、オプション引数で subok=False を指定すると、サブクラスを引き継がず、配列として生成されます。

以下のコードでは、配列のサブクラスであるマトリックスを生成しています。

In [1]:
import numpy as np
#  ndarrayのサブクラスである、np.matrixを生成します。
arr1 = np.array(np.mat('1 2; 3 4'), subok=True)
arr1
Out[1]:
matrix([[1, 2],
        [3, 4]])

以下のコードでは、 subok=False を指定して、サブクラスは引き継がないようにしています。

In [2]:
''' 「subok=False」にすると新しい配列はndarrayクラスで生成されます。 '''
arr2 = np.empty_like(arr2, subok=False)
arr2
Out[2]:
array([[                  6,                   0],
       [3458764513820540928, 3471831545649718635]])

型を確認しましょう。

In [3]:
'''  元の配列と新しい配列のクラスは異なります。  '''
print(type(arr1))
print(type(arr2))
<class 'numpy.matrixlib.defmatrix.matrix'>
<class 'numpy.ndarray'>

形状の変更

元の配列の形状を引き継がずに、任意の形状にしたい場合は、オプション引数 shape= を使います。以下のコードでご確認ください。

In [1]:
import numpy as np
arr1 = np.arange(8).reshape(2, 4)
arr1
Out[1]:
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])
In [2]:
np.empty_like(arr1, shape=(4, 2))
Out[2]:
array([[-3458764513820540928,  1152930290498592301],
       [                   4,                    0],
       [                   0,                    0],
       [-2305834223321951144,     1125899906842624]])

3. まとめ

以上が、np.empty関数とnp.empty_like関数の使い方です。

np.empty関数はゼロから未初期化配列を生成します。一方で、np.empty_like関数は既にある配列の属性を引き継いだ上で要素のみ未初期化の値にした新しい配列を生成します。

それぞれ使い分けると便利です。

なお、初期化配列を生成する関数は、他にも次のものがあります。これらも併せて確認しておくと良いでしょう。

目的に応じて使い分けましょう。



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる