こんにちは、小澤です。
前回、教科書『Pythonによるあたらしいデータ分析の教科書(第2版)』の4.1.2章「NumPyでデータを扱う」の前半部分を取り上げ、NumPyの基本的な概念を説明しました。今回は、同じ章の後半(97ページ〜120ページ)を取り上げ、NumPyの配列操作に関する基本的な関数について説明します。
インデックス
NumPyのインデックスは、配列や行列などの多次元配列要素にアクセスするための機能です。
- インデックスは、配列内の特定の要素にアクセスするために使用されます。
- インデックスは0から始まります。
- 負のインデックスを使用すると、配列の末尾から逆向きに要素にアクセスできます。
- 1次元配列では、単一のインデックスを使用して要素にアクセスします。
- 多次元配列では、各次元ごとにインデックスを指定して要素にアクセスします。
import numpy as np arr = np.array([1, 2, 3, 4, 5]) print(arr[0]) # 1 print(arr[-1]) # 5 matrix = np.array([[1, 2, 3], [4, 5, 6]]) print(matrix[0, 0]) # 1 print(matrix[1, -1]) # 6 |
スライス
NumPyのスライスは、Pythonの標準的なリストのスライスと似ていますが、多次元配列の場合により強力な機能を提供します。
- スライスは、配列内の範囲を取得するために使用されます。
- [開始インデックス:終了インデックス:ステップ]の形式で指定します。
- 開始インデックスは含まれ、終了インデックスは含まれないことに注意してください。
- ステップは省略可能で、デフォルト値は1です。負のステップを指定すると、逆順にスライスします。
import numpy as np arr = np.array([1, 2, 3, 4, 5]) print(arr[1:4]) # [2 3 4] print(arr[:3]) # [1 2 3] print(arr[::2]) # [1 3 5] matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(matrix[0:2, 1:]) # [[2 3] [5 6]] print(matrix[:, ::-1]) # 列を逆順にする [[3 2 1] [6 5 4] [9 8 7]] |
- [:3]は、配列の先頭からインデックス3(3番目の要素)の手前までの部分配列を取得するスライスです。つまり、0番目から2番目の要素までを含む部分配列が返されます。
- [::2]は、ステップサイズを2として配列をスライスする表記です。これにより、配列内の全ての要素を2つおきに取得することができます。つまり、0番目の要素から始まり、1番目、3番目、5番目… といったように、2つおきの要素が含まれる部分配列が返されます。
データ再代入
NumPyにおいても、要素や部分配列に新しい値を割り当てる、データの再代入ができます。
import numpy as np # NumPyの配列でのデータ再代入 arr_np = np.array([1, 2, 3, 4, 5]) # [1 2 3 4 5] arr_np[2] = 10 # [ 1 2 10 4 5] arr_np[:3] = [6, 7, 8] # [6 7 8 4 5] # Pythonの標準の一次元配列でのデータ再代入 arr_py = [1, 2, 3, 4, 5] # [1, 2, 3, 4, 5] arr_py[2] = 10 # [1, 2, 10, 4, 5] arr_py[:3] = [6, 7, 8] # [6, 7, 8, 4, 5] |
- arr_np[:3]は、NumPy配列の最初の3つの要素をスライスします。これによって、最初の3つの要素が新しい値[6, 7, 8]に置き換えられます。
参照とコピー
NumPyの配列における参照とコピーの挙動は、Pythonのリストなどの通常のオブジェクトとは異なる場合があります。
- NumPyの配列の参照は、元の配列を指す新しい配列を示します。つまり、元の配列と参照配列は同じデータを共有します。
- 参照を変更すると、元の配列も変更されます。
import numpy as np arr = np.array([1, 2, 3, 4, 5]) # arr_refはarrの参照 arr_ref = arr # arr_refを変更すると、arrも変更される arr_ref[0] = 100 print(arr) [100 2 3 4 5] |
- 一方、NumPyの配列のコピーは、元の配列とは別のメモリ領域に新しい配列を作成します。つまり、元の配列とコピー配列は独立しています。
- コピー配列を変更しても、元の配列は変更されません。
import numpy as np arr = np.array([1, 2, 3, 4, 5]) # arr_copyはarrのコピー arr_copy = arr.copy() # arr_copyを変更しても、arrは変更されない arr_copy[0] = 100 print(arr) [1 2 3 4 5] |
便利な関数
NumPyは、さまざまな目的に使用できる便利な関数を提供しています。以下に、いくつか関数を紹介します。
- numpy.arange() … 連続した数値の配列(数列)を生成します。
- numpy.random.random() … 指定した形状のランダムな数値の配列を生成します。
(データ分析の教科書では、最新のRandom Generatorを使った乱数の取り扱いが紹介されています。) - numpy.zeros() … 指定した形状のゼロで満たされた配列を生成します。
- numpy.eye() … 単位行列を生成します。
- numpy.full() … 指定した形状と値で満たされた配列を生成します。
- numpy.linspace() … 指定した範囲内で等間隔の数値を生成します。
import numpy as np # 0から9までの整数を生成(9は含まない) arr1 = np.arange(10) print(arr1) [0 1 2 3 4 5 6 7 8 9] # 3×3のランダムな浮動小数点数の配列を生成 arr2 = np.random.random((3, 3)) print(arr2) [[0.11066847 0.82093694 0.84845133] [0.78152041 0.98987843 0.46749433] [0.41180856 0.96117571 0.75792748]] # 2×2のゼロ配列を生成 arr3 = np.zeros((2, 2)) print(arr3) [[0. 0.] [0. 0.]] # 3×3の単位行列を生成 arr4 = np.eye(3) print(arr4) [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]] # 2×2の値が7の配列を生成 arr5 = np.full((2, 2), 7) print(arr5) [[7 7] [7 7]] # 0から10までの区間を10等分した配列を生成 arr6 = np.linspace(0, 10, 10) print(arr6) [ 0. 1.11111111 2.22222222 3.33333333 4.44444444 5.55555556 6.66666667 7.77777778 8.88888889 10. ] |
配列の操作
NumPyを使用して配列の差分、連結、分割、転置、および次元の追加を行うには以下のようにします。
- numpy.diff() … 差分の計算
- numpy.concatenate() … 配列の連結
- numpy.split() … 配列の分割
- numpy.transpose() … 配列の転置
- numpy.newaxis … 次元の追加
import numpy as np # 隣接する要素の差分を計算 arr = np.array([1, 3, 6, 10, 15]) diff_arr = np.diff(arr) print(diff_arr) [2 3 4 5] # 配列を連結 arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) concatenated_arr = np.concatenate((arr1, arr2)) print(concatenated_arr) [1 2 3 4 5 6] # 配列を3つに分割 arr = np.array([1, 2, 3, 4, 5, 6]) split_arr = np.split(arr, 3) print(split_arr) [array([1, 2]), array([3, 4]), array([5, 6])] # 配列を転置 arr = np.array([[1, 2, 3], [4, 5, 6]]) transposed_arr = np.transpose(arr) print(transposed_arr) [[1 4] [2 5] [3 6]] # 次元を追加 arr = np.array([1, 2, 3]) new_arr = arr[:, np.newaxis] print(new_arr) [[1] [2] [3]] |
まとめ
今回は、NumPyの配列を操作する基本的な関数について説明しました。NumPyは、配列を操作するための多くの便利な関数を提供しています。これらの関数を理解し、上手に活用することで、効率的なデータ処理や数値計算を行うことができます。次回は、さらに応用的な機能について学びます。それによって、より幅広い分野でNumPyを活用することができるようになると思います。ぜひ次回もお楽しみに。
お知らせ
今回のコラムはいかがでしたでしょうか? 少しでも皆様の学習のお役に立てると嬉しいです。
インターネットアカデミーでは Python 講座が充実しています。
Python 認定スクールにもなっているため、質の良い知識を得ることができます。
基礎を習得した先に新たな目標を設定し、目指していくために大変良い場所となります。
「プログラミングは独学でもなんとかなる」という情報もありますが、新しいことを学んでいく際の近道は「プロに教えてもらうこと」かと思います。
インターネットアカデミーはキャリアサポートも充実しており、一人ひとりに専任のキャリアプロデューサーがサポートしてくれるため中途半端になることがありません。
ご興味ある方は各講座のページを覗いてみてください。無料カウンセリングもできます。
https://www.internetacademy.jp/course/programming/chair_py.html