NumPyのfull関数で全要素が指定の値の初期化配列を生成する方法

numpy.full関数は、全ての要素が同じ任意の値の初期化配列を作成する関数です。これと同じように、既存の配列のshapeやdtype等の属性を引き継いだ上で、要素だけを任意の値で初期化した新しい配列を作成するnumpy.full_like関数というものもあります。

このページでは、これら両方の関数について解説します。初期化配列の作成はよく行うことなので、しっかりと理解を深めておきましょう。

目次

1. np.full関数の使い方

1.1. 書式

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

numpy.full

書き方:

np.full(shape, fill_value, dtype=None, order='C')

パラメーター:

shape: 整数 または 整数のシーケンス
生成する配列のshapeを指定する。
fill_value: スカラー
初期値を指定する。
dtype: データ型(オプション)
データ型を指定する。デフォルトのNoneでは、fill_valueのデータ型を引き継ぐ。
order: ’C’ か ‘F’ (オプション)
配列のメモリレイアウトを C-order(行優先)か Fortran-order(列優先)のどちらかから選択。デフォルトは ‘C’。

戻り値: 

out: ndarray
指定した shape, fill_value, dtype, order の新しい配列

一緒に確認したい関数:

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

1.2. サンプルコード

それでは、サンプルコードを見ながら使い方を確認していきましょう。以下のコードでは、長さ5で初期値が0.1の1次元配列を生成しています。

In [1]:
import numpy as np
#  shape(5, )で初期値が0.1の初期化配列を生成
np.full(5, 0.1)
Out[1]:
array([0.1, 0.1, 0.1, 0.1, 0.1])

多次元配列を生成する場合は、shapeはタプルで渡さなければいけません。間違えて数値で渡さないようにしましょう。

In [2]:
#  多次元配列の場合、shapeをタプルで渡す
np.full((2, 5), 10)
Out[2]:
array([[10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10]])

少しテクニカルな方法も見ておきましょう。np.full関数を使って要素が空の配列を生成するには、次のように fill_valueにnp.nanを渡します。

In [3]:
np.full((2, 5), np.nan)
Out[3]:
array([[nan, nan, nan, nan, nan],
       [nan, nan, nan, nan, nan]])

次のコードのように、無限大の浮動小数点数(float型)を表す inf を初期値に指定することも可能です。

In [4]:
#  無限大 inf を初期値に指定することも可能
np.full((2, 2), np.inf)
Out[4]:
array([[inf, inf],
       [inf, inf]])

ブロードキャストを利用して、初期値を次のように指定することも可能です。ブロードキャストについては『覚えておくべきNumPy配列のブロードキャストのルール』で解説しています。

以下のコードをご覧ください。

In [5]:
#  初期値をブロードキャストして指定
np.full((3, 3), [1, 2, 3])
Out[5]:
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

オプション引数 dtype= order=
これらのオプション引数については、以下で説明していますが使用することはほとんどありません。気になる場合はご確認ください。

オプション引数 dtype=

オプション引数 dtype= を指定することで、生成する配列のdtypeを明示的に宣言することができます(デフォルト値はNone)。

もし、第二引数で指定した初期値の型と、オプション引数 dtype= で指定した値の型が異なる場合は、後者が優先されます。

なお、NumPyの配列の型の一覧や、指定する際の書き方などは『NumPyのdtype属性の一覧と参照・指定・変更方法』で解説しています。

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

In [1]:
import numpy as np

#  dtypeでfloatを指定(dtypeよる指定が優先)
arr1 = np.full((2, 3), 1, dtype=float)
print(arr1)
print(arr1.dtype, '\n')

#  dtypeでint型を指定(dtypeによる指定が優先)
arr2 = np.full((2, 4), 1.0, dtype=int)
print(arr2)
print(arr2.dtype)
[[1. 1. 1.]
 [1. 1. 1.]]
float64 

[[1 1 1 1]
 [1 1 1 1]]
int64

なお、第二引数で小数を渡して、オプション引数で dtype=int を指定する場合、つまりfloat型をint型に変換する場合、NumPyでは、少数点以下は切り捨てになります。

四捨五入や丸めではないので注意しましょう。

In [2]:
'''  値でfloatを渡し、dtype=intを指定した場合、
     小数点数以下は切り捨て  '''
arr3 = np.full(5, 0.9, dtype=int)
print(arr3, '\n')

arr4 = np.full(5, 1.9, dtype=int)
print(arr4)
[0 0 0 0 0] 

[1 1 1 1 1]

ビット数も指定することができます。

In [3]:
'''  ビット数も指定可能  '''
#  float32を指定
arr5 = np.full(5, 0.1, dtype=np.float32)
print(arr5)
print(arr5.dtype, '\n')

#  int8を指定
arr6 = np.full(5, 10, dtype='int16')
print(arr6)
print(arr6.dtype)
[0.1 0.1 0.1 0.1 0.1]
float32 

[10 10 10 10 10]
int16

ただし、ビット数をPython3標準の64ビット(複素数は128ビット)以外にする場合、思わぬところで丸めのルールの違いによる誤差が発生してしまいます。そのため、本当に必要と確信できる場合以外は、使わない方が無難です。

オプション引数 order=

もう一つのオプション引数 order= では、配列の要素をメモリに格納する時の方式を指定することができます。

NumPyの方式には、C言語方式とFortran方式があります。C言語方式は行を軸に、Fortran方式は列を軸に、そのデータをメモリに格納していきます。

以下のコードでご確認ください。

In [4]:
'''  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]]

もし、これらを指定したい場合は、次のように書くことによって可能です。

In [5]:
#  C言語方式を指定(デフォルト)
arr10 = np.full((2, 3), 10, order='C')
print(arr10, '\n')

#  Fortran方式を指定
arr11 = np.full((2, 3), 10, order='F')
print(arr11)
[[10 10 10]
 [10 10 10]] 

[[10 10 10]
 [10 10 10]]

np.full関数では、全ての要素が同じ値になるので見た目で確認することはできませんが、指定の通りの方式でメモリには格納されています。

2. np.full_like関数の使い方

さて、np.full関数と同じく、任意の初期値の配列を生成する関数に np.full_like関数があります。

np.full_like関数は、既存の配列のshape, dtype, order, サブクラスを引き継いだ上で、要素を任意の値で初期化した新しい配列を生成します。そのため、np.full関数と似ているとは言っても同じ感覚で使うものではありません。ここでしっかり確認しておきましょおう。

2.1. 書式

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

numpy.full_like

書き方:

np.full_like(a, fill_value, dtype=None, order='K', subok=True)

パラメータ:

a: array_like オブジェクト(リストや配列など)
生成する配列のshapeを指定する。
fill_value: スカラー
初期値を指定する。
dtype: データ型(オプション)
データ型を指定する。デフォルトのNoneでは、fill_valueのデータ型を引き継ぐ。
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と同じshape, dtype, order, サブクラスで、要素を任意の値で初期化した新しい配列

一緒に確認したい関数:

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

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

2.2. サンプルコード

np.full_like関数は、既存の配列のshape, dtype, orderを引き継いで、要素の値を任意のものに変更した新しい配列を生成します。

以下の、要素が整数の配列 arr1を使って確認しましょう。

In [1]:
import numpy as np
arr1= np.arange(6).reshape(2, 3)
arr1
Out[1]:
array([[0, 1, 2],
       [3, 4, 5]])

np.full_like関数は元の配列の属性を引き継ぐ

np.full_like関数を使う上で重要な点は、この関数は元の配列の属性を強く引き継ぐということです。

例えば、上で作成した要素が整数(int型)の配列 arr1np.full_like関数に渡して、不動総数点数(float型)の値で初期化した新しい配列を生成してみましょう。

In [2]:
#  dtypeは元の配列のものが優先のため上書きされません。
arr2 = np.full_like(arr1, 1.1)
arr2
Out[2]:
array([[1, 1, 1],
       [1, 1, 1]])

ご覧のように、引数のfill_valueで1.1の浮動小数点数(float型)を指定しているにも関わらず、生成された配列の要素は整数((int型)になっています。

これは、元の配列の要素の型と、fill_valueで指定した数値の型が異なる場合、前者が優先されるようになっているからです。そのため小数点以下が切り捨てられて、整数の1に直されています。

このように元の配列の属性を維持しようとする点が、np.full_like関数の大きな特徴です。これは配列のshapeと要素の型(dtype)だけではなく、メモリオーダーやサブクラスも当てはまります。

そのため、np.full_like関数では、新しく生成する配列に元々の配列の属性を受け継ぎたくない場合は、それをオプション引数で指定する必要があります。

それぞれ見ていきましょう。

要素の型を変更(dtype=)

np.full_like関数で元々の配列のdtypeを上書きしたい場合は、オプション引数 dtype= を指定する必要があります

以下のコードでは、オプション引数で dtype=floatと指定することで、元の配列のdtypeのint型を、新しい配列ではfloat型に上書きしています。

In [3]:
arr3  = np.full_like(arr1, 1.1, dtype=float)
arr3
Out[3]:
array([[1.1, 1.1, 1.1],
       [1.1, 1.1, 1.1]])
In [4]:
#  要素が空の配列を生成
arr4 = np.full_like(arr1, np.nan, dtype=float)
arr4
Out[4]:
array([[nan, nan, nan],
       [nan, nan, nan]])

メモリオーダーの変更(order=)

同じように、オプション引数 order= で、メモリへの要素の格納方式を上書きすることもできます。

それぞれ以下のコードでご確認ください。

In [5]:
'''  orderの上書き  '''
#  C言語方式の配列を生成
arr5 = np.arange(6).reshape(2, 3, order='C')
print('元の配列: \n', arr5.flags, '\n')

#  Fortran方式で上書き
arr6 = np.full_like(arr5, 10, order='F')
print('Fortran方式で上書き: \n', arr6.flags, '\n')

#  Aは、元の配列がCならCに、FならFにする
arr7 = np.full_like(arr5, 10, order='A')
print("order='A': \n", arr7.flags, '\n')

#  Kは、元の配列に近い並べ方をする
arr8 = np.full_like(arr5, 10, order='K')
print("order='K': \n", arr8.flags)
元の配列: 
   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  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
 

order='A': 
   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
 

order='K': 
   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

サブクラスの変更(subok=)

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

これも実際に見てみましょう。

まず、以下のコードでは、ndarrayのサブクラスであるmatrixを生成しています。

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

この配列を引き継いで、新たな配列arr10を生成します。この時、「subok=True(デフォルト値)」なら、サブクラスをそのまま引き継ぎます。

なお、「subok=True」はデフォルトなので、わざわざ書く必要はありませんが、ここでは明示的にするためにあえて書くことにします。

In [7]:
arr10 = np.full_like(arr9, 10,  subok=True)
arr10
Out[7]:
matrix([[10, 10],
        [10, 10]])

subok=False にすると、元のサブクラスは引き継がずに、配列(ndarray)として生成されます。

In [8]:
arr11 = np.full_like(arr9, 10,  subok=False)
arr11
Out[8]:
array([[10, 10],
       [10, 10]])

shapeの変更

np.full_like関数では、新たなshapeを指定することもできます。以下のコードをご覧ください。

In [9]:
arr12 = np.full_like(arr1, 10, shape=(3, 2))
arr12
Out[9]:
array([[10, 10],
       [10, 10],
       [10, 10]])

3. まとめ

以上がnumpy.full関数とnumpy.full_like関数の使い方です。

np.full関数は、全ての要素が同じ指定の値を持つ新しい初期化配列を生成します。

一方で、np.full_like関数は、既存の配列の属性(shape, dtype, メモリオーダー, サブクラス)を引き継いだ上で、要素のみを指定の値で初期化した新しい初期化配列を生成します。

それぞれの違いをしっかり把握した上で使い分けるようにしましょう。

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



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

この記事を書いた人

コメント

コメントする

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

目次
閉じる