[Python] NumPy – 配列(ndarray)をインデックスでスライスする

NumPyの配列(ndarray)をインデックスでスライスすることで、特定の範囲の要素を抽出できます。

スライスの基本的な構文は 配列[start:stop:step] です。

start は開始インデックス、stop は終了インデックス(このインデックスは含まれません)、step はステップ数を指定します。

例えば、arr[1:5:2] はインデックス1から4までの要素を2つ飛ばしで取得します。

startstep を省略すると、デフォルトで先頭や1が使用されます。

この記事でわかること
  • NumPyのスライス機能の基本
  • 多次元配列のスライス方法
  • 条件に基づく要素の抽出
  • 整数配列インデックスの活用
  • スライスと条件付き代入の応用

目次から探す

インデックスによるスライスの基本

NumPyの配列(ndarray)を操作する際、スライスは非常に便利な機能です。

スライスを使うことで、配列の特定の部分を簡単に取得したり、変更したりすることができます。

スライスの基本構文

スライスの基本構文は以下のようになります。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# スライスの使用
sliced_array = array[start:stop:step]

ここで、startはスライスの開始インデックス、stopは終了インデックス(このインデックスは含まれません)、stepはインデックスの間隔を指定します。

スライスの範囲指定(start, stop, step)

スライスの範囲指定は、以下のように行います。

import numpy as np
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 1から5までの要素を取得
sliced_array = array[1:6]  # 1, 2, 3, 4, 5
print(sliced_array)
[1 2 3 4 5]

この例では、インデックス1から5までの要素を取得しています。

スライスの省略記法

スライスでは、startstopstepを省略することも可能です。

import numpy as np
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 最初から5までの要素を取得
sliced_array1 = array[:5]  # 0, 1, 2, 3, 4
print(sliced_array1)
# 5から最後までの要素を取得
sliced_array2 = array[5:]  # 5, 6, 7, 8, 9
print(sliced_array2)
# 全ての要素を取得(ステップ2)
sliced_array3 = array[::2]  # 0, 2, 4, 6, 8
print(sliced_array3)
[0 1 2 3 4]
[5 6 7 8 9]
[0 2 4 6 8]

負のインデックスを使ったスライス

NumPyでは、負のインデックスを使用して配列の末尾から要素を取得することもできます。

import numpy as np
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 最後の3つの要素を取得
sliced_array = array[-3:]  # 7, 8, 9
print(sliced_array)
[7 8 9]

この例では、負のインデックスを使って配列の最後の3つの要素を取得しています。

スライスの結果として得られるビューとコピーの違い

スライスを使用すると、元の配列のビュー(参照)またはコピーが得られます。

ビューは元の配列とメモリを共有しているため、ビューを変更すると元の配列にも影響を与えます。

一方、コピーは独立した配列であり、変更しても元の配列には影響しません。

import numpy as np
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# スライスによるビューの取得
view_array = array[2:5]
view_array[0] = 99  # ビューを変更
print(array)  # 元の配列も変更される
print(view_array)  # ビューの変更が反映される
[ 0  1 99  3  4  5  6  7  8  9]
[99  3  4]

このように、スライスの結果がビューである場合、元の配列にも影響を与えることに注意が必要です。

多次元配列のスライス

NumPyでは、多次元配列(ndarray)を扱うことができ、スライスを使って特定の部分を簡単に取得することができます。

ここでは、2次元配列や3次元以上の配列のスライスについて解説します。

2次元配列のスライス

2次元配列のスライスは、行と列を指定して行います。

以下の例では、2次元配列から特定の行と列を取得します。

import numpy as np
# 2次元配列の作成
array_2d = np.array([[0, 1, 2], 
                     [3, 4, 5], 
                     [6, 7, 8]])
# 1行目から2行目まで、全ての列を取得
sliced_array = array_2d[0:2, :]  # [[0, 1, 2], [3, 4, 5]]
print(sliced_array)
[[0 1 2]
 [3 4 5]]

この例では、1行目と2行目を取得しています。

3次元以上の配列のスライス

3次元配列の場合も、同様に各次元を指定してスライスを行います。

以下の例では、3次元配列から特定のスライスを取得します。

import numpy as np
# 3次元配列の作成
array_3d = np.array([[[0, 1], [2, 3]], 
                      [[4, 5], [6, 7]], 
                      [[8, 9], [10, 11]]])
# 1つ目の配列の全ての要素を取得
sliced_array = array_3d[0, :, :]  # [[0, 1], [2, 3]]
print(sliced_array)
[[0 1]
 [2 3]]

この例では、3次元配列の最初の配列を取得しています。

複数軸に対するスライスの指定方法

複数の軸に対してスライスを指定することも可能です。

以下の例では、2次元配列から特定の行と列を同時に指定して取得します。

import numpy as np
# 2次元配列の作成
array_2d = np.array([[0, 1, 2], 
                     [3, 4, 5], 
                     [6, 7, 8]])
# 1行目と2行目の1列目と2列目を取得
sliced_array = array_2d[0:2, 1:3]  # [[1, 2], [4, 5]]
print(sliced_array)
[[1 2]
 [4 5]]

この例では、1行目と2行目の1列目と2列目を取得しています。

スライスと軸の順序変更

NumPyでは、配列の軸の順序を変更することもできます。

transposeメソッドを使用して、軸の順序を変更した後にスライスを行うことができます。

import numpy as np
# 2次元配列の作成
array_2d = np.array([[0, 1, 2], 
                     [3, 4, 5]])
# 軸の順序を変更
transposed_array = array_2d.T  # [[0, 3], [1, 4], [2, 5]]
# 軸を変更した後にスライス
sliced_array = transposed_array[1, :]  # [1, 4]
print(sliced_array)
[1 4]

この例では、配列の軸を変更した後に、特定の行をスライスして取得しています。

これにより、データの視点を変えて操作することが可能になります。

スライスの応用例

NumPyのスライス機能は、単に配列の一部を取得するだけでなく、さまざまな操作に応用できます。

ここでは、スライスを使ったいくつかの応用例を紹介します。

条件に基づくスライス

条件に基づいて配列の要素をスライスすることができます。

以下の例では、配列の中から特定の条件を満たす要素を取得します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 5より大きい要素を取得
sliced_array = array[array > 5]  # [6, 7, 8, 9]
print(sliced_array)
[6 7 8 9]

この例では、配列の中から5より大きい要素を取得しています。

スライスを使った部分配列の変更

スライスを使って、配列の特定の部分を変更することもできます。

以下の例では、配列の一部の値を変更します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 3から5までの要素を変更
array[3:6] = [99, 100, 101]
print(array)
[  0   1   2  99 100 101   6   7   8   9]

この例では、インデックス3から5までの要素を新しい値に変更しています。

スライスを使った配列の反転

スライスを使って配列を反転させることもできます。

以下の例では、配列を逆順に取得します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 配列を反転
reversed_array = array[::-1]
print(reversed_array)
[9 8 7 6 5 4 3 2 1 0]

この例では、スライスのステップを-1にすることで、配列を逆順に取得しています。

スライスを使った配列の結合

スライスを使って、複数の配列を結合することもできます。

以下の例では、2つの配列を結合します。

import numpy as np
# 配列の作成
array1 = np.array([0, 1, 2])
array2 = np.array([3, 4, 5])
# 配列の結合
combined_array = np.concatenate((array1, array2))
print(combined_array)
[0 1 2 3 4 5]

この例では、np.concatenateを使用して2つの配列を結合しています。

スライスを使った配列の分割

スライスを使って、配列を分割することも可能です。

以下の例では、配列を2つの部分に分割します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 配列を分割
first_half = array[:5]  # [0, 1, 2, 3, 4]
second_half = array[5:]  # [5, 6, 7, 8, 9]
print(first_half)
print(second_half)
[0 1 2 3 4]
[5 6 7 8 9]

この例では、配列を前半と後半に分割しています。

スライスを使うことで、配列の特定の部分を簡単に操作することができます。

スライスとブールインデックス

NumPyでは、ブールインデックスを使用して配列の要素を条件に基づいて選択することができます。

スライスと組み合わせることで、より柔軟なデータ操作が可能になります。

ブールインデックスの基本

ブールインデックスは、配列の各要素に対して真偽値(TrueまたはFalse)を持つ配列を作成し、その真偽値に基づいて要素を選択する方法です。

以下の例では、配列の要素が特定の条件を満たすかどうかを確認します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 条件に基づくブールインデックスの作成
boolean_index = array > 5  # [False, False, False, False, False, True, True, True, True, True]
print(boolean_index)
[False False False False False  True  True  True  True  True]

この例では、配列の各要素が5より大きいかどうかを判定し、ブールインデックスを作成しています。

ブールインデックスとスライスの組み合わせ

ブールインデックスを使用して、スライスと組み合わせることで、特定の条件を満たす要素を簡単に取得できます。

以下の例では、配列から5より大きい要素を取得します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# ブールインデックスを使って条件に合う要素を取得
sliced_array = array[array > 5]  # [6, 7, 8, 9]
print(sliced_array)
[6 7 8 9]

この例では、ブールインデックスを使って5より大きい要素を取得しています。

条件に基づく要素の抽出

ブールインデックスを使用することで、複雑な条件に基づいて要素を抽出することも可能です。

以下の例では、配列の要素が偶数であるかつ5より大きい要素を取得します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 偶数かつ5より大きい要素を取得
sliced_array = array[(array > 5) & (array % 2 == 0)]  # [6, 8]
print(sliced_array)
[6 8]

この例では、条件を組み合わせて、偶数でありかつ5より大きい要素を抽出しています。

ブールインデックスを活用することで、データのフィルタリングが非常に簡単になります。

スライスと整数配列インデックス

NumPyでは、整数配列インデックスを使用して、配列の特定の要素を直接指定して取得したり、変更したりすることができます。

スライスと組み合わせることで、より柔軟なデータ操作が可能になります。

整数配列インデックスの基本

整数配列インデックスは、配列のインデックスを整数の配列として指定する方法です。

これにより、特定のインデックスにある要素を一度に取得することができます。

以下の例では、整数配列インデックスを使用して配列の要素を取得します。

import numpy as np
# 配列の作成
array = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# 整数配列インデックスを使って要素を取得
indices = np.array([1, 3, 5])  # 取得したいインデックス
sliced_array = array[indices]  # [20, 40, 60]
print(sliced_array)
[20 40 60]

この例では、指定したインデックスにある要素を一度に取得しています。

整数配列インデックスとスライスの併用

整数配列インデックスとスライスを組み合わせることで、より複雑なデータ操作が可能になります。

以下の例では、スライスを使って配列の一部を取得し、その部分に対して整数配列インデックスを使用します。

import numpy as np
# 配列の作成
array = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# スライスを使って配列の一部を取得
sliced_array = array[2:8]  # [30, 40, 50, 60, 70, 80]
# 整数配列インデックスを使って要素を取得
indices = np.array([0, 2, 4])  # スライス内のインデックス
result_array = sliced_array[indices]  # [30, 50, 70]
print(result_array)
[30 50 70]

この例では、スライスで取得した部分配列から、さらに整数配列インデックスを使って特定の要素を取得しています。

整数配列インデックスを使った要素の変更

整数配列インデックスを使用して、配列の特定の要素を変更することもできます。

以下の例では、指定したインデックスにある要素を新しい値に変更します。

import numpy as np
# 配列の作成
array = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# 整数配列インデックスを使って要素を変更
indices = np.array([1, 3, 5])  # 変更したいインデックス
array[indices] = [99, 88, 77]  # 新しい値を代入
print(array)
[ 10  99  30  88  50  77  70  80  90 100]

この例では、指定したインデックスにある要素を新しい値に変更しています。

整数配列インデックスを使うことで、特定の要素を効率的に操作することができます。

スライスと条件付き代入

NumPyでは、条件付き代入を使用して、特定の条件を満たす要素に対して新しい値を代入することができます。

スライスと組み合わせることで、配列の特定の部分に対して効率的に操作を行うことが可能です。

条件付き代入の基本

条件付き代入は、配列の要素が特定の条件を満たす場合に、その要素に新しい値を代入する方法です。

以下の例では、配列の要素が5より大きい場合に、その要素を100に変更します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 条件付き代入
array[array > 5] = 100
print(array)
[  0   1   2   3   4   5 100 100 100 100]

この例では、5より大きい要素が100に変更されています。

条件付き代入とスライスの組み合わせ

条件付き代入はスライスと組み合わせることで、特定の部分に対して条件を適用することができます。

以下の例では、配列の一部に対して条件付き代入を行います。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# スライスを使って配列の一部を取得
sliced_array = array[5:10]  # [5, 6, 7, 8, 9]
# 条件付き代入
sliced_array[sliced_array > 7] = 200
print(array)
[0  1  2  3  4  5  6  7 200 200]

この例では、スライスで取得した部分配列の中で8と9が200に変更されています。

元の配列にも影響が及んでいることに注意してください。

条件付き代入の応用例

条件付き代入は、データの前処理やフィルタリングに非常に便利です。

以下の例では、配列の要素が偶数の場合にその要素を0に変更します。

import numpy as np
# 配列の作成
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 偶数の要素を0に変更
array[array % 2 == 0] = 0
print(array)
[0 1 0 3 0 5 0 7 0 9]

この例では、偶数の要素がすべて0に変更されています。

条件付き代入を使用することで、特定の条件に基づいて配列の要素を効率的に操作することができます。

よくある質問

スライスで得られるビューとコピーの違いは?

スライスを使用すると、得られる結果は「ビュー」と「コピー」のいずれかになります。

ビューは元の配列とメモリを共有しているため、ビューを変更すると元の配列にも影響を与えます。

一方、コピーは独立した配列であり、変更しても元の配列には影響しません。

例えば、次のようにスライスを行った場合:

import numpy as np
array = np.array([1, 2, 3, 4, 5])
view = array[1:4]  # ビュー
copy = array[1:4].copy()  # コピー
view[0] = 99  # ビューを変更
print(array)  # 元の配列も変更される
print(copy)   # コピーは変更されない
[ 1 99 3 4 5]
[2 3 4]

このように、ビューは元の配列に影響を与えるのに対し、コピーは独立しています。

スライスで配列の形状を変更できますか?

スライス自体では配列の形状を変更することはできませんが、スライスを使用して得られた配列の形状を変更することは可能です。

NumPyのreshapeメソッドを使用することで、スライスした配列の形状を変更できます。

以下の例を見てみましょう。

import numpy as np
array = np.array([[1, 2, 3], [4, 5, 6]])
sliced_array = array[:, 1]  # スライスで1列目を取得
reshaped_array = sliced_array.reshape(2, 1)  # 形状を変更
print(reshaped_array)
[[2]
 [5]]

このように、スライスした結果に対してreshapeを使うことで、形状を変更することができます。

スライスを使って配列の一部を削除する方法は?

スライスを使って配列の一部を削除することは直接的にはできませんが、スライスを利用して新しい配列を作成することで、特定の部分を除外することができます。

以下の例では、配列の特定の範囲を削除する方法を示します。

import numpy as np
array = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 3から5までの要素を削除
new_array = np.concatenate((array[:3], array[6:]))  # [0, 1, 2, 6, 7, 8, 9]
print(new_array)
[0 1 2 6 7 8 9]

この例では、スライスを使って3から5までの要素を除外した新しい配列を作成しています。

元の配列は変更されず、新しい配列が生成されます。

まとめ

この記事では、NumPyのスライス機能について、基本的な使い方から応用例、ブールインデックスや整数配列インデックスとの組み合わせ、条件付き代入の方法まで幅広く解説しました。

スライスを活用することで、配列の特定の部分を効率的に操作できるため、データ処理や分析において非常に役立つ技術です。

ぜひ、実際のプログラミングにおいてスライスを積極的に活用し、データ操作のスキルを向上させてみてください。

  • URLをコピーしました!
目次から探す