【NumPy入門】Pythonでの基本的なスライシングと高度なインデックス参照の使い方
NumPyのndarray(多次元配列)へのインデックス参照は、標準的なPythonの x[obj] 構文を使って行えます。ここで x は配列、obj は選択条件(セレクタ)です。
NumPyで利用できるインデックス参照には、主に以下の3種類があります。
- フィールドアクセス(field access)
- 基本的なスライシング(basic slicing)
- 高度なインデックス参照(advanced indexing)
どの種類のインデックス参照が適用されるかは、obj の内容によって決まります。この記事では、特に「基本的なスライシング」と「高度なインデックス参照」に焦点を当てて解説します。
さらに、高度なインデックス参照は次の2つに分類できます。
- 整数配列によるインデックス参照(Integer array indexing)
- ブール値によるインデックス参照(Boolean indexing)
基本的なスライシング(Basic Slicing)
Pythonのスライシングの概念は、NumPyの基本的なスライシングではn次元へと拡張されています。Pythonの slice オブジェクトは、slice() 関数に start(開始位置)、stop(終了位置)、step(ステップ幅)の3つの引数を渡すことで生成できます。この slice オブジェクトを配列に渡すことで、配列の一部を抽出できます。
例1:sliceオブジェクトを使う方法
import numpy as np arr = np.arange(25) s = slice(2, 21, 4) print(arr[s])
出力結果
[ 2 6 10 14 18]
上の例では、まず arange() 関数を使って ndarray オブジェクト(arr)を作成しています。次に、start=2、stop=21、step=4 を指定して slice オブジェクト(s)を生成します。この slice オブジェクトを ndarray に渡すと、インデックス2から始まり21未満まで、4刻みで要素を取り出した部分配列が得られます。
例2:コロン記法で書く方法
同じプログラムは、おなじみのコロン(:)を使った記法でも書けます。
# 上のプログラムを別の書き方で表現 import numpy as np arr = np.arange(25) s = arr[2:21:4] print(s)
出力結果
[ 2 6 10 14 18]
単一要素の取り出し
# 配列から単一の要素を取り出す import numpy as np arr = np.arange(10) s = arr[9] print(s)
出力結果
9
特定のインデックス以降をスライス
# インデックス3以降の要素を取り出す import numpy as np arr = np.arange(10) s = arr[3:] print(s)
出力結果
[3 4 5 6 7 8 9]
インデックス範囲を指定してスライス
# インデックス3〜7の間の要素を取り出す import numpy as np arr = np.arange(10) s = arr[3:7] print(s)
出力結果
[3 4 5 6]
これらの方法は、下記のように多次元のndarrayにもそのまま適用できます。
# 多次元配列でのスライシング import numpy as np arr = np.array([[[1],[2],[3]], [[4],[5],[6]], [[7],[8],[9]]]) s = arr[1:] print(s)
出力結果
[[[4] [5] [6]] [[7] [8] [9]]]
高度なインデックス参照(Advanced Indexing)
整数配列によるインデックス参照(Integer Array Indexing)
まず、簡単な整数の配列を作成してみましょう。
arr = np.array([[1, 2], [3, 4], [5, 6]]) print(arr)
出力結果
[[1 2] [3 4] [5 6]]
この多次元ndarrayから、行インデックス [0, 1, 2]、列インデックス [1, 0, 1] に対応する特定の要素を選択してみます。
import numpy as np arr = np.array([[1, 2], [3, 4], [5, 6]]) s = arr[[0, 1, 2], [1, 0, 1]] print(s)
出力結果
[2 3 6]
インデックス0を指定すると、配列の最初の行が取得できます。
>>> arr = np.array([[1, 2], [3, 4], [5, 6]]) >>> print(arr[0]) [1 2]
同様に、配列から単一の要素を取り出すことも可能です。たとえば、行インデックス1・列インデックス1の要素を指定すると、値4が得られます。
>>> print(arr[[1], [1]]) [4]
さらに、加算などの算術演算を組み合わせれば、演算後の特定のインデックスの値を取得することもできます。
>>> print(arr[[1], [1]] + 1) [5]
ご覧のとおり、取得した値は1増えていますが、元の配列自体は変更されていません。
>>> arr
array([[1, 2],
[3, 4],
[5, 6]])一方、配列の値を実際に更新したい場合は、代入演算子を使用します。これにより、元の配列の該当要素が直接書き換えられます。
>>> arr[[1], [1]] += 1
>>> arr
array([[1, 2],
[3, 5],
[5, 6]])ブール値によるインデックス参照(Boolean Indexing)
ブールインデックス参照は、ブール演算の評価結果に基づいて要素を選択したい場合に使用します。条件を満たす要素だけを柔軟に抽出できる、非常に強力な手法です。
>>> arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
>>> arr
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])値が1である要素だけを返します。
>>> arr[arr == 1] array([1])
偶数の要素だけを返します。
>>> arr[arr % 2 == 0] array([ 0, 2, 4, 6, 8, 10])
-
Pythonの日付と時刻の基本!datetimeモジュールの型・定数・主要メソッドを徹底解説
Pythonで日付や時刻を操作するには、標準ライブラリのdatetimeモジュールを使用します。このモジュールには、日付・時刻オブジェクトとして「naive(ナイーブ)」と「aware(アウェア)」という2種類のタイプが存在します。 naive(ナイーブ)オブジェクトは、他の日時オブジェクトと明確に区別するために必要な情報(タイムゾーン情報など)を十分に持たないオブジェクトです。UTC(協定世界時)やローカル時刻といった基準を明示的に含まないため、その意味はプログラマー自身が管理する必要があります。 aware(アウェア)オブジェクトは、夏時間(DST)などのアルゴリズム的・政治的な時刻調整
-
Pythonで配列リスト内の0と1を分離する方法
リスト内包表記(List Comprehension)はPythonで広く使われている人気のテクニックです。ここでは、この手法を活用して配列内の0と1を分離してみましょう。 まず、ユーザーから入力を受け取って配列を作成します。配列の要素は0と1がランダムな順序で含まれているものとします。そして、0を配列の左側へ、1を右側へと分離させます。 具体的には、配列を走査しながら要素を2つの異なるリストに振り分けます。片方のリストには0だけを、もう片方のリストには1だけを格納し、最後にその2つのリストを連結することで目的の結果を得られます。 実行例 入力: a=[0,1,1,0,0,1] 出力: [0