Python
 Computer >> コンピューター >  >> プログラミング >> Python

【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])
  1. Pythonの日付と時刻の基本!datetimeモジュールの型・定数・主要メソッドを徹底解説

    Pythonで日付や時刻を操作するには、標準ライブラリのdatetimeモジュールを使用します。このモジュールには、日付・時刻オブジェクトとして「naive(ナイーブ)」と「aware(アウェア)」という2種類のタイプが存在します。 naive(ナイーブ)オブジェクトは、他の日時オブジェクトと明確に区別するために必要な情報(タイムゾーン情報など)を十分に持たないオブジェクトです。UTC(協定世界時)やローカル時刻といった基準を明示的に含まないため、その意味はプログラマー自身が管理する必要があります。 aware(アウェア)オブジェクトは、夏時間(DST)などのアルゴリズム的・政治的な時刻調整

  2. Pythonで配列リスト内の0と1を分離する方法

    リスト内包表記(List Comprehension)はPythonで広く使われている人気のテクニックです。ここでは、この手法を活用して配列内の0と1を分離してみましょう。 まず、ユーザーから入力を受け取って配列を作成します。配列の要素は0と1がランダムな順序で含まれているものとします。そして、0を配列の左側へ、1を右側へと分離させます。 具体的には、配列を走査しながら要素を2つの異なるリストに振り分けます。片方のリストには0だけを、もう片方のリストには1だけを格納し、最後にその2つのリストを連結することで目的の結果を得られます。 実行例 入力: a=[0,1,1,0,0,1] 出力: [0