numpy.ones_like関数で既存配列から要素が1の初期化配列を生成する方法

np.ones_like関数は、既にある配列の形状・データ型・メモリレイアウトなどの属性を引き継いで、要素のみ1にした新しい配列を生成する関数です。このページでは、この関数の使い方について解説します。

なお、ゼロから要素が1の初期化配列を生成する関数として、np.ones関数が用意されています。これについては『numpy.ones関数で要素が1の初期化配列を生成する方法』で解説しています。使用感が異なりますので、併せて確認しておくと良いでしょう。

それでは、np.ones_like関数の使い方を見ていきましょう。

目次

1. 書式

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

numpy.ones_like

書き方:

np.ones_like(a, 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と同じ形状、データ型、メモリレイアウト、サブクラスで、要素を1で初期化した新しい配列

一緒に確認したい関数:

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

2. サンプルコード

それでは、サンプルコードを見ながら、使い方を実際に確認していきましょう。

np.ones_like関数に、配列を渡すと、その配列の属性を引き継いで、要素を1で初期化した新しい配列を生成します。以下のコードをご覧ください。

In [1]:
import numpy as np
#  元となる配列を生成
arr1 = np.arange(6).reshape(2, 3)
print(arr1, '\n')

#  arr1と同じ形状, データ型, メモリレイアウトで要素を1で初期化した配列を生成
arr2 = np.ones_like(arr1)
print(arr2)
[[0 1 2]
 [3 4 5]] 

[[1 1 1]
 [1 1 1]]

元の配列はshape(2, 3)、dtype=intなので、それらの属性を引き継いでいます。明示的に書いてはいませんが、元の配列のorderはC言語方式なので、それも引き継いでいます。

元の配列の要素の型が浮動小数点数(float型)だったとしたら、np.ones_like関数はそれを引き継ぎます。

以下のコードで確認しましょう。

In [2]:
'''  元の配列の要素がfloatの場合  '''

#  要素の型がfloat型の配列を生成
arr3 = np.arange(6, dtype=float).reshape(2, 3)
print(arr3, '\n')

#  np.ones.like()は元の配列のデータ型を引き継ぐ
arr4 = np.ones_like(arr3)
print(arr4)
print(arr4.dtype)
[[0. 1. 2.]
 [3. 4. 5.]] 

[[1. 1. 1.]
 [1. 1. 1.]]
float64

このように、np.ones_like関数は元の配列の属性を引き継ぎます。もし、いずれかの属性を変更したい場合はオプション引数で指定する必要があります。次に、そのオプション引数について見ていきましょう。

データ型の変更

オプション引数 dtype=で、任意のデータ型に上書きすることができます。

以下のコードでは、元の配列arr5のデータ型はcomplex型ですが、numpy.ones_likeでarr6を生成するときにint型を指定しています。

In [3]:
'''  dtypeを上書き  '''

#  要素の型がcomplex型の配列を生成
arr5 = np.arange(6, dtype=complex).reshape(2, 3)
print(arr5, '\n')

#  要素の型がint型でnp.ones.like()で初期化
arr6 = np.ones_like(arr5, dtype=int)
print(arr6)
print(arr6.dtype)
[[0.+0.j 1.+0.j 2.+0.j]
 [3.+0.j 4.+0.j 5.+0.j]] 

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

メモリレイアウトの変更

メモリレイアウト(メモリに格納する時の要素の並び)には、C言語方式とFortran方式があります。NumPyのデフォルトはC言語方式です。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]]

np.ones_like関数は、元の配列のメモリレイアウトを引き継ぎます。これを上書きしたい場合は、オプション引数 order= を指定します。

In [5]:
'''  Fortran方式をC言語方式に、C言語方式をFortran方式に上書き  '''

#  C言語方式で上書き
arr7 = np.ones_like(arr_f, order='C')
print(arr7, '\n')

#  Fortran形式の並びで初期化
arr8 = np.ones_like(arr_c, order='F')
print(arr8)
[[1 1 1]
 [1 1 1]] 

[[1 1 1]
 [1 1 1]]

サブクラスの変更

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

オプション引数で subok=False と指定すると、サブクラスを引き継がず、配列(ndarray)として生成されます。ちなみに、「subok」は「sub(サブクラス)でok(いいか)?」という意味です。

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

まず、配列のサブクラスであるマトリックスを生成しています。

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

デフォルトでは subok=True なので、np.ones_like関数はサブクラスを引き継ぎます。

In [7]:
''' デフォルトの「subok=True」では元の配列のサブクラスを引き継ぎます。 '''
arr10 = np.ones_like(arr9, subok=True)
arr10
Out[7]:
matrix([[1, 1],
        [1, 1]])

subok=False を指定すると、サブクラスは引き継がずに配列を生成します。

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

In [8]:
''' subok=False にすると新しい配列はndarrayクラスで生成されます。 '''
arr11 = np.ones_like(arr9, subok=False)
arr11
Out[8]:
array([[1, 1],
       [1, 1]])

形状の変更

NumPyのver1.17からは、配列の形状も変更できるようになっています。以下のコードで確認しましょう。

In [1]:
import numpy as np
# 1次元配列を生成
x = np.arange(9)

# 形状を 3x3 の2次元配列に変換して初期化
np.ones_like(x, shape=(3, 3))
Out[1]:
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

3. まとめ

以上がnp.ones_like関数の使い方です。np.ones関数との最大の違いは、np.ones_like関数は既存の配列の属性を受け継ぐという点です。両者はうまく使い分けられると便利です。

そのためにもnp.ones関数の使い方も確認しておくと良いでしょう。

なお、同じように、既存の配列の属性を引き継いで初期化配列を生成する関数には以下のものもあります。

これらも使い分けると良いでしょう。



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

この記事を書いた人

コメント

コメントする

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

目次
閉じる