すぐわかる!NumPyのおおまかな使い方

41, 2019-07-12

目次

NumPyでPythonの計算を楽に

NumPyとはPythonの数値計算のためのライブラリです。
NumPyを使うと配列の計算や行列の計算が簡単にできるようになります。

この記事を読めばNumPyの「おおまかな」使い方がわかります。
NumPyの機能は非常にたくさんあります。
この記事だけですべてを説明するとライターが指を骨折してしまうので、一部の機能を取り上げています。

NumPyは人工知能の計算などでも頻繁に使われているライブラリです。
NumPyの使い方を覚えて数値計算で楽をしましょう!

NumPyのインストール方法

NumPyを使うにはpipなどを使って環境にnumpyをインストールします。

$ pip install numpy

我らの味方、pipを崇めよ

NumPyのインポート方法

NumPyを使うには最初にnumpyをインポートする必要があります。
numpyはnpというエイリアスでインポートされるのが慣例のようです。

import numpy as np

空の配列の作成

NumPyにはnumpy.ndarrayという計算用の配列があります。
この配列を使うことで多種多様な計算を行うことが可能です。

空の配列を作成するには↓のようにnp.array([])を呼び出します。

import numpy as np

# 空の配列の作成
x = np.array([])

print(type(x))
# <class 'numpy.ndarray'>

print(x)
# []

1次元の配列を作成

NumPyで1次元の配列を作成するには、Pythonのリストをnp.array関数に渡します。
↓の例では[1, 2, 3]のリストをもとに1次元配列を作成しています。

作成した配列は例えばx[0]のように、普通のリストのようにアクセスすることが可能です。
またnumpy.ndarrayは配列の要素数を得るsizeのようにたくさんの属性を持っています。その一部をご紹介します。

import numpy as np

# 1次元配列の作成
x = np.array([1, 2, 3])

print(x)
# [1 2 3]

# 0番目の要素にアクセス
print(x[0])
# 1

# 配列の要素数
print(x.size)
# 3

# 配列の形状
print(x.shape)
# (3,)

# バイト数
# int64(8バイト) * 3要素 = 24バイト
print(x.nbytes)
# 24

2次元の配列を作成

NumPyで多次元の配列を作成するには↓のようにネストしたリストをnp.array関数に渡します。

x.shapeで配列の形状が変わってることに注意してください。
x.shape(2, 3)と出力されています。
これは配列の形状が2行3列だという意味です。

import numpy as np

# 2次元配列の作成
x = np.array([
    [1, 2, 3],
    [4, 5, 6],
])

print(x)
# [[1 2 3]
#  [4 5 6]]

# 1次元目0番目、2次元目0番目の要素にアクセス
print(x[0][0])
# 1

# 配列の要素数
print(x.size)
# 6

# 配列の形状
print(x.shape)
# (2, 3)

# バイト数
# int64(8バイト) * 6要素 = 48バイト
print(x.nbytes)
# 48

3次元の配列を作成

3次元の配列を作成するにはさらにリストを入れ子にしてnp.array関数に渡します。
奥ゆきも加わるとなかなかカオスですね。
物理学ではこれに時間も加わるというから信じられません。

import numpy as np

# 3次元配列の作成
x = np.array([
    [
        [1, 2, 3],
        [4, 5, 6],
    ],
    [
        [7, 8, 9],
        [10, 11, 12],
    ],
])

print(x)
# [[[ 1  2  3]
#   [ 4  5  6]]
#
#  [[ 7  8  9]
#   [10 11 12]]]

# 1次元目0番目、2次元目0番目、3次元目0番目の要素にアクセス
print(x[0][0][0])
# 1

# 配列の要素数
print(x.size)
# 12

# 配列の形状
print(x.shape)
# (2, 2, 3)

# バイト数
# int64(8バイト) * 12要素 = 96バイト
print(x.nbytes)
# 96

配列の要素のデータ型

配列の要素には型があります。
これも整数や実数のリストをnp.arrayに渡すことで自動で判別してくれます。

配列の持つデータ型はdtype属性で確認できます。

import numpy as np

# 配列はint64型
x = np.array([1, 2])
print(x.dtype)
# int64

# 配列はfloat64型
x = np.array([1.0, 2.0])
print(x.dtype)
# float64

# 整数と実数を複合すると?
# 結果はfloat64型
x = np.array([1, 2.0])
print(x.dtype)
# float64

配列をfor文で回す

np.arrayで作成した配列をfor文で回すことも出来ます。

import numpy as np

# 1次元配列をfor文で回す
x = np.array([1, 2])
for el in x:
    print(el)
# 1
# 2

# 2次元配列をfor文で回す
x = np.array([
    [1, 2],
    [3, 4],
])
for row in x:
    print(row)
# [1 2]
# [3 4]

ブロードキャスト機能

ブロードキャスト

NumPyには便利な演算機能としてブロードキャスト機能が用意されています。
この機能を使うことで配列に対して簡単に演算することが出来ます。

簡単な例を見てみましょう。
↓では1次元配列を作成して各要素に4を掛けています。
演算結果はnumpy.ndarrayで返ってきます。

たった1行で全ての要素に対して演算できていることがわかります。

import numpy as np

# 1次元配列の作成
x = np.array([1, 2, 3])
print(x)
# [1 2 3]

# ブロードキャストで各要素に4を掛ける
y = x * 4
print(y)
# [ 4  8 12]

print(type(y))
# <class 'numpy.ndarray'>

便利だな~

多次元配列へのブロードキャスト

もちろん多次元配列に対しても同じようにブロードキャストが可能です。

import numpy as np

# 2次元配列の作成
x = np.array([
    [1, 2],
    [3, 4],
])
print(x)
# [[1 2]
#  [3 4]]

y = x * 4
print(y)
# [[ 4  8]
#  [12 16]]

配列同士のブロードキャスト

2次元配列に対して1次元配列をブロードキャストすることも出来ます。
2次元配列の各行に対して1次元配列の要素が演算されていることがわかります。

import numpy as np

# 2次元配列の作成
x = np.array([
    [1, 2],
    [3, 4],
])

# 1次元配列の作成
y = np.array([10, 20])

# xにyを演算させる
# yがxの各次元に対して演算されていることがわかる
# 細かく見ると
#   1 * 10
#   2 * 20
#   3 * 10
#   4 * 20
# という演算が行われる
z = x * y
print(z)
# [[10 40]
#  [30 80]]

要素数が異なる配列の演算はエラーになる

要素数が異なる配列同士の演算はエラーになります。

import numpy as np

# 要素数が異なる配列の演算はエラーになる
x = np.array([1, 2, 3])
y = np.array([4, 5])
z = x + y
# ValueError: operands could not be broadcast together with shapes (3,) (2,)

単一要素の配列の演算

要素が1つしかない配列は、ほかの配列にブロードキャストすることが可能です。

import numpy as np

# 要素1の配列の演算は各要素に対して行われる
x = np.array([1, 2, 3])
y = np.array([4])
z = x + y
print(z)
# [5 6 7]

要素数が同じ配列同士の演算

要素数が同じ配列同士は演算することが可能です。
↓では1次元配列同士を加算しています。
結果は配列で返ってきます。

import numpy as np

# 要素数が同じ配列の場合、各要素が対応する要素に対して演算を行う
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
z = x + y
print(z)
# [5 7 9]

print(type(z))
# <class 'numpy.ndarray'>

配列同士の四則演算

配列同士の四則演算は以下のように簡単に行えます。
各要素に対応する要素が演算されていることがわかります。

import numpy as np

x = np.array([1, 2]) + np.array([3, 4])
print(x)
# [4 6]

x = np.array([1, 2]) - np.array([3, 4])
print(x)
# [-2 -2]

x = np.array([1, 2]) * np.array([3, 4])
print(x)
# [3 8]

x = np.array([1, 2]) / np.array([3, 4])
print(x)
# [0.33333333 0.5       ]

配列への代入演算

もちろん配列へ代入演算することも可能です。

import numpy as np

x = np.array([1, 2])
x += np.array([3, 4])
print(x)
# [4 6]

x = np.array([1, 2])
x -= np.array([3, 4])
print(x)
# [-2 -2]

配列から特定のインデックスの要素を得る

配列から特定のインデックスの要素をまとめて抜き出したい場合もNumPyなら簡単に可能です。
見慣れない演算ですが、numpy.ndarrayの添え字に配列を使うことで、指定したインデックスの要素を抜き出せます。

import numpy as np

x = np.array([1, 2, 3, 4])

# xの0番目、2番目の要素を取得する
y = x[np.array([0, 2])]
print(y)
# [1 3]

比較演算で条件にマッチした要素を抜き出す

配列からある条件にマッチする要素を集めたいとします。
多くのプログラマーはfor文とif文を使うことで実現していますが、NumPyならもっとスマートに書くことができます。
numpy.ndarrayの添え字に比較演算した結果の配列を与えることで、条件にマッチした要素を簡単に抜き出せます。

import numpy as np

# 比較演算子で各要素を比較する
x = np.array([1, 2, 3, 4])
y = x > 2
print(y)
# [False False  True  True]

# 添え字に比較演算の結果を渡すと、比較で真になった要素を取り出せる
# 2以上の要素を抜き出す
y = x[x > 2]
print(y)
# [3 4]

numpy.ndarrayの便利な関数、メソッド

関数

numpy.ndarrayは多数の便利なメソッドを持っています。
ごくごく一部ですが紹介します。

flattenで多次元配列を正規化する

flattenを使えば多次元配列を1次元配列にすることができます。

import numpy as np

# 2次元配列を作成
x = np.array([
    [1, 2],
    [3, 4],
])

# 2次元配列を1次元に
y = x.flatten()
print(y)
# [1 2 3 4]

allで全ての要素が真かチェックする

allを使えばすべての要素が真かどうかチェックすることが出来ます。
配列に偽の要素が含まれていたらallはFalseを返します。

import numpy as np

# 全ての要素が真ならTrue
x = np.array([1, 2])
print(x.all())
# True

# 偽の要素が含まれていたらFalse
x = np.array([1, 0])
print(x.all())
# False

anyで真の要素が含まれているかチェックする

anyを使えば配列に真の要素が含まれているかどうか簡単にチェックできます。

import numpy as np

# ひとつでも真の要素が含まれていたらTrue
x = np.array([1, 0])
print(x.any())
# True

# 全ての要素が偽ならFalse
x = np.array([0, 0])
print(x.any())
# False

argsortでソートしたインデックス列を得る

argsortは見慣れないメソッドですが、このメソッドは配列をソートした場合のインデックスの配列を返します。
後述するsortのほうが一般的ですね。

import numpy as np

# ソートした配列のインデックスを取得する
x = np.array([2, 1, 3])
indices = x.argsort()
print(indices)
# [1 0 2]

# ソートされたインデックスで配列にアクセスする
for index in indices:
    print(x[index])
# 1
# 2
# 3
# 結果はもちろんソートされている

astypeで配列をキャストする

astypeを使えば簡単に配列の型変換ができます。

import numpy as np

# floatを含んだ配列をintにキャストする
x = np.array([1.2, 2.5, 3])
y = x.astype(int)
print(y)
# [1 2 3]

chooseで行列の要素を抜き出す

chooseを使うことで簡単に行列の要素を抜き出すことが出来ます。
たとえば行列の斜めの要素や、横の要素もchooseで抜き出せます。

import numpy as np

# 正方行列
x = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
])

y = np.choose([0], x)
print(y)
# [1 2 3]

y = np.choose([1], x)
print(y)
# [4 5 6]

y = np.choose([2], x)
print(y)
# [7 8 9]

# 行列の斜めの要素(右肩下がり)
y = np.choose([0, 1, 2], x)
print(y)
# [1 5 9]

# 行列の斜めの要素(右肩上がり)
y = np.choose([2, 1, 0], x)
print(y)
# [7 5 3]

# 行列の平行な要素
y = np.choose([1, 1, 1], x)
print(y)
# [4 5 6]

clipで最小値、最大値の範囲内で要素を抜き出す

clipを使えば設定した最小値、最大値の範囲内で要素を抜き出せます。

import numpy as np

# minの最小値、maxの最大値の範囲内に調整して配列を取得する
x = np.array([1, 5, 10])
y = x.clip(min=3, max=7)
print(y)
# [3 5 7]

x = np.array([1, 5, 10])
y = x.clip(min=0, max=7)
print(y)
# [1 5 7]

copyで配列をコピーする

copyは馴染みのあるメソッドです。
このメソッドは配列をコピーします。

import numpy as np

# 配列のコピーを作成する
x = np.array([1, 2])
y = x.copy()
x[0] = 3 # ホントにコピー?参照じゃないの?
print(y)
# [1 2]
# コピーでした

fillで埋め尽くす

fillを使えば特定の値で配列を埋めることができます。

import numpy as np

# 3で配列を埋める
x = np.array([1, 2])
x.fill(3)
print(x)
# [3 3]

max, minで最大値、最小値を得る

max, minで配列から最大値、最小値を得ることが出来ます。

import numpy as np

# 配列から最大値と最小値を得る
x = np.array([5, 2, 10])

print(x.max())
# 10

print(x.min())
# 2

meanで平均値を得る

meanで簡単に平均値を得られます。

import numpy as np

# 配列の平均値をとる
x = np.array([2, 8, 20])

# (2 + 8 + 20) / 3 = 10
print(x.mean())
# 10.0

reshapeで配列の形状を変える

配列の形状が気に入らないならreshapeで形状を変化させることが出来ます。
↓では2行3列の配列を、3行2列の配列に変形しています。

import numpy as np

# 新しい形状の配列を作成する
# 2行3列の配列を
x = np.array([
    [1, 2, 3],
    [4, 5, 6],
])

# 3行2列の配列にする
y = x.reshape((3, 2))
print(y)
# [[1 2]
#  [3 4]
#  [5 6]]

# 要素数が同じじゃないとエラーになる
x.reshape((3, 3))
# ValueError: cannot reshape array of size 6 into shape (3,3)

sortで配列をソートする

みんな大好きなsortを使えば案の定、配列をソートすることが可能です。

import numpy as np

# 昇順でソート
x = np.array([5, 1, 3])
y = np.sort(x)
print(y)
# [1 3 5]

# 降順でソート
x = np.array([5, 1, 3])
y = np.sort(x)[::-1]
print(y)
# [5 3 1]

# 多次元配列の場合は?
x = np.array([
    [4, 2, 3],
    [3, 1, 2],
])

# 行をソート
y = np.sort(x, axis=0)
print(y)
# [[3 1 2]
#  [4 2 3]]

# 列をソート
y = np.sort(x, axis=1)
print(y)
# [[2 3 4]
#  [1 2 3]]

sumで合計値を得る

配列内の値の合計を得たい場合はsumが使えます。

import numpy as np

x = np.array([1, 2, 3])
print(x.sum())
# 6

x = np.array([
    [1, 2, 3],
    [4, 5, 6],
])
print(x.sum())
# 21

NumPyを使って快適な計算ライフを

いかがでしたでしょうか。
ここで紹介した機能はNumPyのほんの一部です。
NumPyを使って快適な計算ライフを送りましょう。

以上、narupoでした。

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク