NumPy配列に要素・行・列を追加!np.append()の活用術
データ処理において、既存のデータに新しい情報を追加する操作は頻繁に発生します。NumPy配列(ndarray)の場合も例外ではありません。この記事では、NumPy配列の末尾に要素、行、列を効率的に追加するための**np.append()**関数について、その使い方と注意点を詳しく解説します。
np.append()とは?
np.append()は、NumPy配列の末尾に指定した値や配列を追加するための関数です。一次元配列はもちろん、多次元配列に対しても行や列として新しいデータを追加できます。ただし、np.append()は元の配列を変更するのではなく、新しい配列を生成して返す点に注意が必要です。
基本的な要素の追加(一次元配列)
まずは、一次元配列に要素を追加する最もシンプルなケースを見てみましょう。
import numpy as np
arr = np.array([1, 2, 3])
# 要素4を追加
new_arr = np.append(arr, 4)
print(f"元の配列: {arr}") # 出力: 元の配列: [1 2 3]
print(f"追加後の配列: {new_arr}") # 出力: 追加後の配列: [1 2 3 4]
# 複数の要素を追加
another_new_arr = np.append(arr, [5, 6])
print(f"複数の要素追加後の配列: {another_new_arr}") # 出力: 複数の要素追加後の配列: [1 2 3 5 6]
多次元配列への行・列の追加
np.append()は、axis引数を指定することで、多次元配列に対して行(軸0)または列(軸1)としてデータを追加できます。
行(axis=0)の追加
配列の末尾に新しい行を追加するには、axis=0 を指定します。追加する行の列数(形状の最後の次元)は、元の配列と一致している必要があります。
import numpy as np
arr_2d = np.array([[1, 2, 3],
[4, 5, 6]])
# 新しい行 [7, 8, 9] を追加
new_row = np.array([[7, 8, 9]]) # 行として追加するためには2次元にする
appended_arr_row = np.append(arr_2d, new_row, axis=0)
print(f"行追加後の配列:\n{appended_arr_row}")
# 出力:
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
ポイントは、追加するデータも追加したい軸の次元を考慮した形状にする必要があることです。例えば、2次元配列に行を追加する場合は、追加する行も2次元配列(例: [[7, 8, 9]])である必要があります。
列(axis=1)の追加
配列の末尾に新しい列を追加するには、axis=1 を指定します。追加する列の行数(形状の最初の次元)は、元の配列と一致している必要があります。
import numpy as np
arr_2d = np.array([[1, 2, 3],
[4, 5, 6]])
# 新しい列 [10, 20] を追加
new_col = np.array([[10], [20]]) # 列として追加するためには2次元にする
appended_arr_col = np.append(arr_2d, new_col, axis=1)
print(f"列追加後の配列:\n{appended_arr_col}")
# 出力:
# [[ 1 2 3 10]
# [ 4 5 6 20]]
ここでも、追加するデータは[[10], [20]]のように、列として結合できる形状にする必要があります。
np.append()を使用する際の注意点と代替案
np.append()は便利ですが、特に大きな配列に対して頻繁に使用すると、パフォーマンスの問題が発生する可能性があります。
1. パフォーマンスの問題
np.append()は新しい配列を生成するため、元の配列が大きい場合、データのコピーに時間がかかり、メモリ消費も大きくなります。特にループ内で何度もnp.append()を使用するのは避けるべきです。
悪い例(避けるべき):
import numpy as np
# パフォーマンスが悪い例
result = np.array([])
for i in range(1000):
result = np.append(result, i)
この場合、ループごとに新しい配列が作成され、非効率です。
2. より効率的な代替案
パフォーマンスが重要な場合や、大規模なデータに対する追加操作が必要な場合は、以下の代替案を検討してください。
a. 空のリストに追加し、最後にNumPy配列に変換
最も一般的なパフォーマンス対策は、まずPythonのリストに要素を追加していき、最後にnp.array()でNumPy配列に変換する方法です。
import numpy as np
# 効率的な例
data_list = []
for i in range(1000):
data_list.append(i)
result_efficient = np.array(data_list)
print(f"効率的な追加の結果(一部): {result_efficient[:5]}...")
# 出力: 効率的な追加の結果(一部): [0 1 2 3 4]...
b. np.concatenate()を使用
np.concatenate()は、既存の複数の配列を結合するのに特化した関数で、np.append()よりも柔軟かつ効率的です。行や列の追加にはこちらを推奨します。
import numpy as np
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6]])
# 行の追加 (axis=0)
concatenated_rows = np.concatenate((arr1, arr2), axis=0)
print(f"np.concatenateで行追加:\n{concatenated_rows}")
# 出力:
# [[1 2]
# [3 4]
# [5 6]]
arr3 = np.array([[7], [8]])
# 列の追加 (axis=1)
concatenated_cols = np.concatenate((arr1, arr3), axis=1)
print(f"np.concatenateで列追加:\n{concatenated_cols}")
# 出力:
# [[1 2 7]
# [3 4 8]]
np.concatenate()は、引数として結合したい配列のタプルを取る点に注意してください。
まとめ
np.append()は、NumPy配列に手軽に要素や行・列を追加できる便利な関数です。特に小規模な配列の操作には十分役立ちます。しかし、大規模なデータや頻繁な追加操作が必要な場合は、パフォーマンスの観点からnp.append()の利用は慎重に行い、代わりにPythonリストへの追加からの変換や、より効率的なnp.concatenate()の使用を検討することをお勧めします。状況に応じて最適な方法を選択し、NumPyを最大限に活用しましょう!

