Numpy 超入門

Python で集計可視化する際によく使われるライブラリ Numpy の基本的な使い方について説明します。

Contents

NumPy

NumPy とは、Python コードで数値計算を行ったり、行列や配列を扱うための機能を備えたライブラリです。ここでは基本的な操作について述べるに留めます。より詳しく NumPy について知りたい場合は 公式ドキュメント を参照ください。

基本操作

  • narray 配列の生成
  • 算術計算
  • 代表的な関数

まず、ライブラリをインポートします。

import numpy as np

ここで as np とは読み込んだライブラリをnpと呼ぶを宣言することを意味しています。

配列の生成

NumPy の配列を生成するにはメソッドnp.array()を使います。このメソッドの引数は Python のリストです。 まず、1次元の配列を作成してみましょう。1次元とは1列に要素が並んだリストのような構成のことを指します。

1次元配列

1次元の配列を numpy で生成するには下記のようにnp.array()の引数に1次元のリストを渡します。

# 1次元配列の作成
arr = np.array([1.0, 2.0, 3.0])
print(arr)
[1. 2. 3.]
# typeの確認
print(type(arr))
<class 'numpy.ndarray'>

np.array()メソッドで作成されたオブジェクトはnumpy.ndarrayというデータ型であることがわかります。要素の取り出しはPythonのリストと同様な書き方で取り出すことができます。

arr[1]
2.0

N次元配列

1次元だけでなくN次元の配列を生成することもできます。例えば、2次元配列を生成するにはnp.array()の引数にリストを要素にもったリストを渡します。

# 2次元配列の作成(インデントには見やすくする以上の意味はありません。)
A = np.array([
              [2.0, 4.0]
              ,[3.0, 5.0]    
])
print(A)
[[2. 4.]
 [3. 5.]]

N次元配列の要素を取得するにはN個分のインデックスを指定する必要があります。いま生成した配列は2次元配列なので、最初のインデックスでは列が指定され取得されます。

# 1行目が取得される(インデックスは0から始まる)
A[0]
array([2., 4.])
# 1行目2列目の要素の取得
A[0][1]
4.0

算術計算

基本的に配列同士の算術では、配列の要素数が同じもので算術計算を行います。配列の要素数が異なる場合にはエラーが出ます。

# 足し算は各要素がそれぞれ足し合わされる
x = np.array([0.0, 1.0])
y = np.array([3.0, 5.0])
x + y
array([3., 6.])
# 配列の要素数が異なる場合にはエラーが出る
a = np.array([1.0, 0.0])
b = np.array([3.0, 2.0, 4.0])
a + b
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-64-c3dc6f7f5c4c> in <module>()
      2 a = np.array([1.0, 0.0])
      3 b = np.array([3.0, 2.0, 4.0])
----> 4 a + b

ValueError: operands could not be broadcast together with shapes (2,) (3,) 

ブロードキャスト

配列とスカラー値の算術では、配列の各要素とスカラー値がそれぞれ計算されます。これは「ブロードキャスト」と呼ばれる機能の一つです。

# 配列とスカラー値の算術
z = np.array([3.0, 4.0, 6.0])
z / 2
array([1.5, 2. , 3. ])
# ただし配列の要素数が 1 の場合にはそれはスカラー値のように扱われ、ブロードキャストする
a = np.array([1.0, 0.0])
b = np.array([3.0])
a + b
array([4., 3.])

先程、A という2×2の行列を生成しました。もう一つ2×2の行列を生成して、算術計算を試してみましょう。

B = np.array([
              [1.0, 3.0]
              ,[4.0, 2.0]
])
print(B)
array([[3., 7.],
       [7., 7.]])

行列の各要素同士が足し合わされた配列が返されます。この結果は「数学」で学んだ「行列」の計算結果と同じになります。

一方で掛け算はどうでしょうか。

# 算術演算子による掛け算
A * B
array([[ 2., 12.],
       [12., 10.]])

この結果から、算術演算子による掛け算は2次元配列の各要素同士に作用し結果を返すことがわかります。これは「数学」で学んだ「行列」の計算結果とは異なりますので注意してください。

行列の掛け算

「行列」の掛け算の結果を得たい場合はnp.dot()メソッドが用意されています。

np.dot(A,B)
array([[18., 14.],
       [23., 19.]])

算術演算子による演算は配列の各要素同士に作用するので、割り算を行うこともできます。「数学」で出てくる「行列」には割り算はありません。

A / B
array([[2.        , 1.33333333],
       [0.75      , 2.5       ]])

最後にN次元配列における、ブロードキャストの様子を見てみましょう。

# 2次元配列とスカラー値
A * 5
array([[10., 20.],
       [15., 25.]])

行列 \(A = \left(  \begin{array}{cc}  2 & 4 \\  3 & 5  \end{array}  \right)\) に1次元配列の \( (1, 0) \) が足されますが、これは1次元配列が、\(\left(  \begin{array}{cc}  1 & 0 \\  1 & 0  \end{array}  \right)\) のようにブロードキャストされて演算が実行されていると解釈することができます。

代表的な関数

ここでは、集計によく使われる関数について紹介します。

a = np.arange(10)
print(a)
[0 1 2 3 4 5 6 7 8 9]

最大値、最小値、合計値、平均値、分散、標準偏差

配列を引数にする使い方もできます。(例:max(a)など)

# 最大値
a.max()
9
# 最小値
a.min()
0
# 合計値
a.sum()
45
# 平均値
a.mean()
4.5
# 分散
a.var()
8.25
# 標準偏差
a.std()
2.8722813232690143

N次元配列に対してはaxisという引数を指定することで、次元に沿った計算を指定することもできます。

# 対象の行列の表示
print(A)
[[2. 4.]
 [3. 5.]]
# axisを指定しないとすべての要素を足し合わします
print(A.sum()) 
14.0
# 1つ下の階層の要素(今回だと、[2,4]と[3,5]というリストの要素)について
# 1つ目の要素をそれぞれ取り出して足し合わされることが走査的に行われます
print(A.sum(axis=0)) 
[5. 9.]
# 2つ下の階層の要素(今回だと2と4というintの要素)について
# 1つ目の要素をそれぞれ取り出して足し合わされることが走査的に行われます
print(A.sum(axis=1))
[6. 8.]