[Python, Numpy] 配列へのアクセス・スライス

ここでは、pythonプログラミングの基本である、Numpy配列へのアクセス方法ついて解説します。まずは、Google Colaboratoryの使い方 を参考に、プログラミングの環境に移動しましょう。ローカルに環境を構築している方は、そちらでもokです。

配列へのアクセスとは

前回の記事で、Numpyにより配列を定義する方法を説明しました。今回はその続きとして、配列へのアクセス方法を解説しました。ここで、アクセスという新しい言葉が登場しました。これを理解するために、まず、10行10列の2次元配列を考えましょう(各行と列に与えられている数字はなんでもいいです)。このとき、

  • 3行4列目だけを取り出したい。
  • 2〜4行目、かつ、3〜6列目だけを取り出したい。
  • 2行目だけを取り出したい。
  • 3列目だけを取り出したい。
  • 2〜4行目だけを取り出したい。
  • 3〜6列目だけを取り出したい。
  • 3行目から最後の行までを取り出したい。
  • 4列目から最後の列までを取り出したい。
  • 最初から3行目までを取り出したい。
  • 最初から4列目までを取り出したい。
  • 最初から3行目、かつ、4列目から最後の列までを取り出したい。

といった操作をしなければならないことがたくさんあります。このように、事前に定義されている配列に対し、任意の要素を取り出すには、取り出す場所を指定しなければなりません。このような抽出個所の指定を、配列へのアクセスと呼びます。

この練習を行うために、下記のような10行10列の2次元配列を定義しておきましょう。

import numpy as np
a = np.array([
              [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],
              ])
print(a)
print("変数aの次元は", np.ndim(a), "であり、サイズは", np.shape(a), "です。")

カンマとコロン

記号が混ざると説明の意味を理解できないので、以下に整理しておきます。まずはこれを覚えましょう。

  • カンマ(,)
  • コロン(:)

3行4列目だけ

b = a[3, 4]
print(b)

ポイントは、配列の後ろに四角かっこをつけ、アクセスしたい行番号と列番号をカンマ区切りで記入するという点です。行→列の順番に書くということを覚えるようにしましょう(行は上から下に進んでいく並び、列は左から右に進んでいく並びです)。

2〜4行目、かつ、3〜6列目だけ

c = a[2:5, 3:7]
print(c)

先ほどはピンポイントな要素指定でしたが、今回は範囲があります。カンマの左が行指定で、カンマの右が列指定という点は、ピンポイントな要素指定の場合と同一です。範囲指定のために、コロン(:)という新しい記号を利用します。これを理解するために、行指定と列指定を分けて考えます。

  • 行指定(カンマの左側)→ 2:5 → 2行目から4行目
  • 列指定(カンマの右側)→ 3:7 → 3列目から6行目

いずれも、最終地点は1を引くという点に注意してください。なお、コロンにより範囲指定を行うことを、スライスと呼びます。

2行目だけ

c = a[2, :]
print(c)

カンマの左が行指定で、カンマの右が列指定でしたね。ですから、2行目を指定していることはわかると思います。一方で、列指定の方はコロン(:)しかありません。実はこれ、コロンの左右の数字(開始・終了地点)が省略されています。この場合、最初から最後までという範囲指定になります。したがって、a[2, :]と書くと、2行目、かつ、最初から最後の列までという指定になり、2行目が丸ごと取り出されます。

3列目だけ

d = a[:, 3]
print(d)

2行目を取り出したい場合と同様です。今回は行と列が逆転します。

2〜4行目だけ

e = a[2:5, :]
print(e)

これまでの応用です。カンマの左に2:5と書くことで2〜4行目が指定され、カンマの右側のコロン(:)により、最初から最後の列が指定されます。

3〜6列目だけ

f = a[:, 3:7]
print(f)

行はすべての範囲とし、列のみ範囲指定を行えばokです。

3行目から最後の行まで

g = a[3:, :]
print(g)

カンマの左側にある行指定で、終了地点のみを省略します。

4列目から最後の列まで

h = a[:, 4:]
print(h)

カンマの右側にある列指定で、終了地点のみを省略します。

最初から3行目まで

i = a[:3, :]
print(i)

カンマの左側にある行指定で、開始地点のみを省略します。

最初から4列目まで

j = a[:, :4]
print(j)

カンマの右側にある列指定で、開始地点のみを省略します。

最初から3行目、かつ、4列目から最後の列まで

k = a[:3, 4:]
print(k)

カンマの左側の行指定で、開始地点を省略します。また、カンマの右側の列指定で、終了地点を省略します。

1次元配列の場合

numpyには、2次元配列以外にも1次元配列がありました。この場合は、行と列の概念がありませんので、より簡単にスライスとアクセスを行うことができます。下記のコードを実行して、挙動を確認してみましょう。

a1d = np.array([0, 1, 2, 3, 4, 5, 6])
print( a1d[3] )
print( a1d[:3] )
print( a1d[5:] )
print( a1d[2:5] )

おわりに

本記事では、numpyにより定義された配列について、任意の箇所や指定された範囲にアクセスする方法を説明しました。numpyを扱う場合は、とても基本的なことになりますので、ぜひ身に付けるようにしましょう。