Python NumPyのarray関数とasarray関数は、どちらもリストやタプルなどの入力データをNumPy配列(ndarray)に変換する機能を提供します。これらの関数は似ていますが、いくつかの違いがあります。この記事では、arrayとasarrayの基本的な使い方と概要を説明し、それらの違い、そして使い分けについて解説します。
1. array の概要と基本的な使い方
概要
np.arrayは、NumPy配列(ndarray)を作成するための基本的な関数です。リスト、タプル、その他の配列状のオブジェクトをNumPy配列に変換します。最大の特徴は、入力がNumPy配列である場合、常に新しい配列(コピー)を作成することです。これにより、元のデータが変更されるのを防ぐことができます。
基本的な使い方
import numpy as np # リストからNumPy配列を作成 my_list = [1, 2, 3] arr_from_list = np.array(my_list) print(f"type: {type(arr_from_list)}, arr: {arr_from_list}") # タプルからNumPy配列を作成 my_tuple = (4, 5, 6) arr_from_tuple = np.array(my_tuple) print(f"type: {type(arr_from_tuple)}, arr: {arr_from_tuple}") # 既存のNumPy配列から新しいNumPy配列を作成(コピー) existing_arr = np.array([7, 8, 9]) new_arr = np.array(existing_arr) # コピーが作成される new_arr[0] = 10 print(f"existing_arr: {existing_arr}") # 元の配列は変更されない print(f"new_arr: {new_arr}")
出力
type: <class 'numpy.ndarray'>, arr: [1 2 3] type: <class 'numpy.ndarray'>, arr: [4 5 6] existing_arr: [7 8 9] new_arr: [10 8 9]
データ型の指定 (dtype)
dtype引数を使って、作成されるNumPy配列のデータ型を指定できます。
my_list = [1, 2, 3] arr_float = np.array(my_list, dtype=float) print(arr_float) arr_int = np.array(my_list, dtype=np.int32) # 明示的にint32を指定 print(arr_int)
出力
[1. 2. 3.] [1 2 3]
メモリレイアウトの指定 (order)
order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。
'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。
arr_c = np.array([[1,2],[3,4]], order='C') # Cスタイル(行優先) arr_f = np.array([[1,2],[3,4]], order='F') # Fortranスタイル(列優先)
2. asarray の概要と基本的な使い方
概要
np.asarrayは、np.arrayと同様に、入力データをNumPy配列に変換する関数です。ただし、np.asarrayは、入力が既にNumPy配列の場合、特定の条件下ではコピーを作成しません。これにより、不要なメモリ使用を避け、パフォーマンスを向上させることができます。
基本的な使い方
import numpy as np # リストからNumPy配列を作成 my_list = [1, 2, 3] arr_from_list = np.asarray(my_list) print(f"type: {type(arr_from_list)}, arr: {arr_from_list}") # タプルからNumPy配列を作成 my_tuple = (4, 5, 6) arr_from_tuple = np.asarray(my_tuple) print(f"type: {type(arr_from_tuple)}, arr: {arr_from_tuple}") # 既存のNumPy配列からNumPy配列を作成(コピーは作成されない可能性がある) existing_arr = np.array([7, 8, 9]) new_arr = np.asarray(existing_arr) # デフォルトではコピーは作成されない new_arr[0] = 10 print(f"existing_arr: {existing_arr}") # 元の配列も変更される print(f"new_arr: {new_arr}")
出力
type: <class 'numpy.ndarray'>, arr: [1 2 3] type: <class 'numpy.ndarray'>, arr: [4 5 6] existing_arr: [10 8 9] new_arr: [10 8 9]
データ型の指定 (dtype)
np.arrayと同様に、dtype引数でデータ型を指定できます。dtypeが入力と異なる場合は、コピーが作成されます。
my_list = [1, 2, 3] arr_float = np.asarray(my_list, dtype=float) # float型に変換(コピーが作成される) print(arr_float) existing_arr = np.array([1,2,3]) arr_float2 = np.asarray(existing_arr, dtype=float) # float型に変換(コピーが作成される) arr_float2[0] = 0.1 print(existing_arr) # もとの配列は変わらない print(arr_float2)
出力
[1. 2. 3.] [1 2 3] [0.1 2. 3. ]
メモリレイアウトの指定(order)
order引数を使うと、多次元配列のメモリ上での配置順序を指定できます。
'C'(C言語スタイル)を選ぶと行優先、'F'(Fortranスタイル)を選ぶと列優先になります。デフォルトは'C'です。
orderが入力と異なる場合は、コピーが作成されます。
arr = np.array([[1, 2], [3, 4]], order='C') arr_f = np.asarray(arr, order='F') # Fortran orderに変更(コピーが作成される)
コピーを制御するcopy引数(NumPy 1.20以降)
np.asarrayにはcopy引数があり、copy=Trueとすると、入力がNumPy配列であっても常にコピーが作成されるようになります。NumPy 1.20で導入されました。
existing_arr = np.array([1,2,3]) arr_copied = np.asarray(existing_arr, copy=True) # コピーを作成 arr_copied[0] = 4 print(existing_arr) # もとの配列は変わらない print(arr_copied)
出力
[1 2 3] [4 2 3]
arrayとasarrayの違い
arrayとasarrayの最も重要な違いは、入力が既にNumPy配列の場合の挙動です。
np.array: 入力がNumPy配列の場合、常に新しい配列(コピー)を作成します。np.asarray: 入力がNumPy配列の場合、原則としてコピーを作成しません。ただし、dtypeやorderが入力と異なる場合、またはcopy=Trueが指定された場合はコピーが作成されます。
array と asarray の使い分け
| 機能 | asarray |
array |
|---|---|---|
| 入力がリスト、タプル等 | NumPy配列に変換 | NumPy配列に変換 |
| 入力がNumPy配列 | - copy=False(デフォルト)で、dtypeとorderが入力と同じ場合: コピーを作成しない(参照を返す)- copy=Trueの場合、dtypeやorderが異なる場合: コピーを作成 |
常にコピーを作成 |
| データ型の指定(dtype) | 可能 | 可能 |
| メモリレイアウトの指定(order) | 可能 | 可能 |
| 使用場面 | - 既存のNumPy配列の不要なコピーを避けたい場合 - 入力がNumPy配列である保証がない場合(リスト、タプル、またはNumPy配列のいずれかである可能性がある場合) - 入力データをNumPy配列として扱いたい場合 |
- 入力に関わらず、常に新しいNumPy配列を作成したい場合 - 元の配列を変更から保護したい場合 |
まとめ
np.arrayとnp.asarrayは、どちらもリストやタプルなどをNumPy配列に変換できます。入力が既にNumPy配列の場合、np.arrayは常にコピーを作成しますが、np.asarrayはデフォルトではコピーを作成しません(条件によってはコピーを作成します)。メモリ効率を重視する場合はnp.asarray、元のデータを保護したい場合はnp.arrayといった形で使い分けます。入力がNumPy配列であるかどうかわからない場合や、NumPy配列で統一的に処理したい場合は、np.asarrayを使うのが便利です。