Pythonライブラリ講座

NumPy配列のインデックスとスライスを解説!条件に応じてデータを抽出する方法

前のページ|次のページ

4章ではNumPy配列(ndarray)の『インデックス』と『スライス』および『ブールインデックス参照』について解説します。

初学者の方にもわかりやすいよう丁寧に解説していますので、ぜひ最後までご覧になってください!

本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。

NumPyPandasMatplotlibScipySeabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。

さらに、学習した内容を定着させられるように各章演習問題を用意しています。

・Pythonでデータ分析ができるようになりたい

・Pythonの基礎事項は一通り学んだので、さらに深く学びたい

このように考えている方はTech Teacherが運営する【Python ライブラリ編】で、Pythonによるデータサイエンスの学習をすることをお勧めします!

なお、『Pythonについて全く知らない』・『Pythonの基礎事項がまだ分かっていない』という方は、まずコチラの【Python 基礎編】で基礎を一通り学習してからライブラリ編に取り掛かりましょう!

<ライブラリ編 目次>

<ライブラリの基礎>
1章:ライブラリとは

<NumPy>
2章:NumPyの概要と配列(ndarray)
3章:統計量や次元の取得/ソート
4章:配列のインデックス
5章:numpy.whereによる条件制御
6章:配列の結合/分割
7章:乱数

<SciPy>
8章:SciPyの概要と基本操作

<Pandas>
9章:SeriesDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い

<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース

<Seaborn>
21章:Seabornの概要と基本操作


本ブログを運営しているTech Teacherは、
プログラミング家庭教師サービスを運営しています。
完全マンツーマン・フルオーダーメイド
あなたが必要な指導を提供します。

インデックスとスライス

Pythonのリストと同様に、NumPyの配列(ndarray)では『インデックス』を用いて要素を参照することができます。

Pythonのリストのインデックスをよく知らないという方向けに、以下の記事ではインデックスを基礎から解説しています。ぜひ参照してください!

ndarrayのインデックス

ndarrayのインデックスは、リストに対するインデックスとほとんど同じように使うことができます。

x = np.arange(0, 100, 10)
print(x)

print(x[3]) #3番目の要素を取り出す
print(x[-1]) #末尾の要素を取り出す
[ 0 10 20 30 40 50 60 70 80 90]
30
90

多次元配列に対するインデックスは、以下のように指定できます。

y = np.arange(9).reshape((3, 3))
print(y)

print(y[0][1]) #0行1列の要素を取り出す
print(y[2]) #2行目をすべて取り出す
[[0 1 2]
 [3 4 5]
 [6 7 8]]
1
[6 7 8]

線形代数で行列に触れたことがある方は、配列を縦に積み重ねてできる行列を考え、行番号と列番号を指定していると考えると分かりやすいと思います。

ndarray インデックス

スライス

スライスを用いることで部分的なデータを取り出すことができます。

スライスとは、配列の要素の一部分を取り出す操作のことです。

配列名[start:stop:step]」とすることで、配列の(start)番目から(stop-1)番目までの要素を(step)個おきに取り出すことができます。

x = np.arange(5)
print(x)

#1番目から2番目までの要素を取り出す
print(x[1:3])

#先頭から3番目までの要素を取り出す
print(x[:4])

#1番目から末尾までの要素を2つおきに取り出す
print(x[1::2])
[0 1 2 3 4]
[1 2]
[0 1 2 3]
[1 3]

ここで注意しておきたいのが、インデックスによる要素の取り出し配列の代入ではコピーではなく参照が行われるという点です。

そのため、スライスなどで参照した配列の要素を変更すると元の配列の要素も変更されます。

arr_origin = np.arange(5)
arr_slice = arr_origin[2:5]
print("元の配列:", arr_origin)
print("スライス:", arr_slice)

#スライスした配列の1番目の要素3を10に変更
arr_slice[1] = 10

#スライスした配列だけでなく、元の配列も変更されている
print("元の配列(変更後):", arr_origin)
print("スライス:(変更後)", arr_slice)
元の配列: [0 1 2 3 4]
スライス: [2 3 4]
元の配列(変更後): [ 0  1  2 10  4]
スライス:(変更後) [ 2 10  4]

配列の要素のコピー

配列の要素を参照するのではなくコピーしたい場合、『np.copy()』を用います。

これにより、コピーした配列を変更しても元の配列が変更されなくなります。

arr_origin = np.arange(5)
arr_slice = np.copy(arr_origin[2:5]) #スライスした配列をコピー

print("元の配列:", arr_origin)
print("スライス:", arr_slice)

#スライスした配列の1番目の要素3を10に変更
arr_slice[1] = 10

#元の配列は変更されていない
print("元の配列(変更後):", arr_origin)
print("スライス:(変更後)", arr_slice)
元の配列: [0 1 2 3 4]
スライス: [2 3 4]
元の配列(変更後): [0 1 2 3 4]
スライス:(変更後) [ 2 10  4]

ブールインデックスによるデータの抽出

ndarrayでは、『ブールインデックス参照』と呼ばれる方法を用いて条件に一致する要素のみを取り出すことができます。

真偽値配列とは

真偽値配列』とは、名前の通り真偽値(True, False)を要素として持つ配列のことです。

ndarrayを含む条件式を書くことで、条件を満たす要素のみがTrueであるような真偽値配列を得ることができます。

以下の例では、条件式を「5以上」とすることで、元の配列で5以上の値を持つ位置がTrueとなっているような配列が得られます。

x = np.array([1, 3, 10, 4, 6, 8, 2, 0, 7])

print(x)
print(x >= 5)
[ 1  3 10  4  6  8  2  0  7]
[False False  True False  True  True False False  True]

真偽値と比較演算子については以下の記事で詳しく解説しています。不安がある方や忘れてしまった方はぜひ参照してください!

ブールインデックス参照

真偽値配列を用いることで、特定の条件を満たす要素のみを取り出す『ブールインデックス参照』を行うことができます。

配列のインデックスとして真偽値配列を指定することでデータを取り出すことができます。

以下の例では、整数を並べた配列から値が5以上の要素のみを取り出しています。

x = np.array([1, 3, 10, 4, 6, 8, 2, 0, 7])

print(x)
print(x[x >= 5]) #ブールインデックス参照
[ 1  3 10  4  6  8  2  0  7]
[10  6  8  7]

また、インデックスとして指定する真偽値配列は別の配列から作成したものでも構いません。

以下の例では、配列xから作成した真偽値配列を用いて、配列yに対してブールインデックス参照を行っています。

x = np.array([1, 3, 10, 4, 6, 8, 2, 0, 7])
y = np.arange(81).reshape((9, 9))
print("x:", x)
print("y:", y)

print()
print(y[x == 10]) #xが10である位置にあるyの要素を取り出す
x: [ 1  3 10  4  6  8  2  0  7]
y: [[ 0  1  2  3  4  5  6  7  8]
 [ 9 10 11 12 13 14 15 16 17]
 [18 19 20 21 22 23 24 25 26]
 [27 28 29 30 31 32 33 34 35]
 [36 37 38 39 40 41 42 43 44]
 [45 46 47 48 49 50 51 52 53]
 [54 55 56 57 58 59 60 61 62]
 [63 64 65 66 67 68 69 70 71]
 [72 73 74 75 76 77 78 79 80]]

[[18 19 20 21 22 23 24 25 26]]

xにおいて10があった3番目の要素がyから取り出されていることが分かります。

『Tech Teacher』3つの魅力

魅力1. オーダーメイドのカリキュラ

『Tech Teacher』では、決められたカリキュラムがなくオーダーメイドでカリキュラムを組んでいます。「質問だけしたい」「相談相手が欲しい」等のご要望も実現できます。

    魅力2. 担当教師によるマンツーマン指導

    Tech Teacherでは完全マンツーマン指導で目標達成までサポートします。
    東京大学を始めとする難関大学の理系学生・院生・博士の教師がが1対1で、丁寧に指導しています。
    そのため、理解できない箇所は何度も分かるまで説明を受けることができます。

    魅力3. 3,960円/30分で必要な分だけ受講

    Tech Teacherでは、授業を受けた分だけ後払いの「従量課金制」を採用しているので、必要な分だけ授業を受講することができます。また、初期費用は入会金22,000円のみです一般的なプログラミングスクールとは異なり、多額な初期費用がかからないため、気軽に学習を始めることができます。

    まとめ

    ・魅力1. 担当教師によるマンツーマン指導

    ・魅力2. オーダーメイドのカリキュラム

    ・魅力3. 3,960円/30分で必要な分だけ受講

    質問のみのお問い合わせも受け付けております。

    4章の練習問題

    以下の練習問題を解いてみましょう。

    練習問題

    問1. 以下の配列xに対して、(1)~(4)を求めてください。ただし、先頭の要素を0番目とします。

    x = np.arange(10)
    

    (1) xの3番目の要素
    (2) xの2番目から5番目までを取り出した配列
    (3) xの先頭から末尾までの値を4つおきに取り出した配列
    (4) xの要素を逆順に取り出した配列

    問2. 以下の配列xに対して、(1)~(2)を求めてください。

    y = np.arange(100)
    

    (1) xから50以下の値のみを取り出した配列
    (2) xから7の倍数のみを取り出した配列

    解答

    問1(クリックして解答を表示)

    x = np.arange(10)
    print("x:", x)
    print()
    
    #(1)
    print(x[3])
    #(2)
    print(x[2:6]) #5番目まで取り出すとき、末尾のインデックスが6となることに注意
    #(3)
    print(x[::4])
    #(4)
    print(x[::-1])
    x: [0 1 2 3 4 5 6 7 8 9]
    
    3
    [2 3 4 5]
    [0 4 8]
    [9 8 7 6 5 4 3 2 1 0]

    問2(クリックして解答を表示)

    y = np.arange(100)
    print("y:", y)
    print()
    
    #(1)
    print(y[y <= 50])
    #(2)
    print(y[y % 7 == 0])
    y: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
     24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
     48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
     72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
     96 97 98 99]
    
    [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
     24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
     48 49 50]
    [ 0  7 14 21 28 35 42 49 56 63 70 77 84 91 98]

    次のページへ