Numpyの使用

numpyとは

数値計算のためのPythonのライブラリです。特に、多次元配列の生成や、配列の一括計算、行列とベクトルの演算ができます。

1 Numpyのインポートと配列の生成

以下のコードはnumpyをインポートをして、エイリアス(別名)npとします。

In [14]:
import numpy as np

#エイリアスは自由に作れます。例えば、
import numpy as mynp

numpyによる1次元配列を作成します。

In [9]:
n_list = [1,2,4,5,6,7,8,9]
n_array = np.array(n_list)
print(n_array)

#または、
n_array = np.array([1,2,4,5,6,7,8,9])
print(n_array)
[1 2 4 5 6 7 8 9]
[1 2 4 5 6 7 8 9]

numpyによる2次元配列を作成します。[]の使用に注意してください。

In [12]:
n_array2 = np.array([[1,2,3,4],[5,6,7,8]])
print(n_array2)
n_array2
[[1 2 3 4]
 [5 6 7 8]]
Out[12]:
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

Numpyは幾つか便利な配列の作成関数を提供しています。

  • linspace(a, b, num): 区間[a,b]の(num-1)等分割を作ります。作成した数列の成分の数はnumです。
  • arange(a,b, step) : aからbまで間隔がhのである数列を作成します。特に、bが配列に入ってないです。
In [23]:
a = 0
b = 1
x1 = np.linspace(a, b, 11)
x2 = np.arange(a, b, 0.1)
print(x1)
print(x2)
[ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1. ]
[ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9]

配列のサイズを調べる

Numpyの配列はshape,ndimという属性を持っています。これを使って、サイズや次元を調べることができます。

  • shape : 配列の行の数、列の数
  • ndim : 配列の次元

注意

  • shape, ndimの後には()はいらないです。
In [67]:
x = np.array([[1,2,3,4],[5,6,7,8]])
print(x)
print("xの形状", x.shape)
print("xの次元", x.ndim)
[[1 2 3 4]
 [5 6 7 8]]
xの形状 (2, 4)
xの次元 2

配列の成分へのアクセス

配列の成分をアクセウするために、以下の方法が使用されています。

  • x[m,n]: xのm行目、n列目の成分(行と列の番号を0から数えます))
  • x[m] : xのm行目
  • x[:,n] : xのn列目 (ここで、「:」は「すべて」を意味しています。)
In [77]:
x = np.array([[1,2,3,4],[5,6,7,8]])
print(x)

print("xの1行目、3列目の成分:",x[1,3])
print("xの1行目のすべての成分:",x[1])
print("xの1列目のすべての成分:",x[:,1])

print("xの1列目のすべての成分をゼロにします。")
x[:,1] = 0
print(x)
[[1 2 3 4]
 [5 6 7 8]]
xの1行目、3列目の成分: 8
xの1行目のすべての成分: [5 6 7 8]
xの1列目のすべての成分: [2 6]
xの1列目のすべての成分をゼロにします。
[[1 0 3 4]
 [5 0 7 8]]

2. Numpyの配列の一括計算

Numpyは多くの数学の関数を提供しています。mathライブラリとは異なって、配列の各成分に関して一括計算ができます。

以下の例では、[0,2*pi]の分割に関して、sin関数の値を計算します。計算した数列を利用して, sin関数のグラフの描画ができます。

比較

  • mathライブラリでは、math.sin(x1)がエラーとなります。
In [35]:
x1 = np.linspace(0, 2*np.pi, 21)
y1 = np.sin(x1)
print(x1)
print(y1)
[ 0.          0.31415927  0.62831853  0.9424778   1.25663706  1.57079633
  1.88495559  2.19911486  2.51327412  2.82743339  3.14159265  3.45575192
  3.76991118  4.08407045  4.39822972  4.71238898  5.02654825  5.34070751
  5.65486678  5.96902604  6.28318531]
[  0.00000000e+00   3.09016994e-01   5.87785252e-01   8.09016994e-01
   9.51056516e-01   1.00000000e+00   9.51056516e-01   8.09016994e-01
   5.87785252e-01   3.09016994e-01   1.22464680e-16  -3.09016994e-01
  -5.87785252e-01  -8.09016994e-01  -9.51056516e-01  -1.00000000e+00
  -9.51056516e-01  -8.09016994e-01  -5.87785252e-01  -3.09016994e-01
  -2.44929360e-16]
In [37]:
import matplotlib.pyplot as plt
plt.plot(x1, y1,'r-o')
plt.grid()

Numpyで作成した配列の四則演算やべき乗も一括計算ができます。

In [46]:
a = np.array([1,2,3,4,5])
b = a + a
c = 2*a
d = a**2
print(a)
print(b)
print(c)
print(d)

#注意:以下のコードはリストであるので、一括計算ができないです。特に、リストに対して、「+、*」の演算子は別の意味をしています。
# a2 = [1,2,3,4,5]
# b2 = a2+a2
# print(b2)
[1 2 3 4 5]
[ 2  4  6  8 10]
[ 2  4  6  8 10]
[ 1  4  9 16 25]

演習1:

Numpyを利用して、以下の関数のグラフを描いてください。 $$ f(x)=sin(x^3)cos(x)+1, \quad x \in [1,2] $$

3. Numpyの便利な関数

Numpyでは、abs,min,maxなどの数学関数が提供されています。以下のコードで使用している関数を確認してください。

Numpyのすべての関数

In [60]:
x = np.linspace(0,2.5*np.pi,21)
y = np.sin(x)

import matplotlib.pyplot as plt
plt.plot(x,y,'ro')
plt.grid()

print("最大値:", np.max(y))
print("最小値:", np.min(y))
print("平均値:", np.average(y))
print("足し算の和:", np.sum(y))

print("絶対値:", np.abs(y))
最大値: 1.0
最小値: -1.0
平均値: 0.143508083146
足し算の和: 3.01366974606
絶対値: [  0.00000000e+00   3.82683432e-01   7.07106781e-01   9.23879533e-01
   1.00000000e+00   9.23879533e-01   7.07106781e-01   3.82683432e-01
   1.22464680e-16   3.82683432e-01   7.07106781e-01   9.23879533e-01
   1.00000000e+00   9.23879533e-01   7.07106781e-01   3.82683432e-01
   2.44929360e-16   3.82683432e-01   7.07106781e-01   9.23879533e-01
   1.00000000e+00]

4. 行列の積

Numpyでは、2次元配列は行列に対応して、行列自身に関する演算や、行列とベクトルの積などの演算ができます。

  • 行列の転置: transpose()
  • 行列のtrace: trace()
  • 行列の逆行列: linalg.inv(A) (ここでは、Numpyの子ライブラリの関数を使用します.)
  • 行列とベクトルの積: 「@」演算子、または、dot()
In [93]:
A = np.array([[1, 2],[3,4]])
print(A)
print("Aの転置:\n", A.transpose())
print("Aのtrace:\n", A.trace())
print("Aの逆行列:\n", np.linalg.inv(A))
[[1 2]
 [3 4]]
Aの転置:
 [[1 3]
 [2 4]]
Aのtrace:
 5
Aの逆行列:
 [[-2.   1. ]
 [ 1.5 -0.5]]
In [102]:
A = np.array([[2, 0],[0,4]])
x = np.array([[1],[2]])
print("行列:\n",A)
print("ベクトル:\n",x)

y=A@x
print("行列Aとベクトルxの積(@演算子を使用):\n",y)
y=A.dot(x)
print("行列Aとベクトルxの積(dot()関数を使用):\n",y)
行列:
 [[2 0]
 [0 4]]
ベクトル:
 [[1]
 [2]]
行列Aとベクトルxの積(@演算子を使用):
 [[2]
 [8]]
行列Aとベクトルxの積(dot()関数を使用):
 [[2]
 [8]]

演習2(option)

$[0,1]$の100分割に利用して、以下の関数の積分の近似値を求めてください。ただし、forループを使用しなく、Numpyの関数sin,sumなどを使用してください。

$$ \int_{0}^1 \sin(x^3) dx $$

演習3(option)

以下の行列Aに関わる連立一次方程式$Ax=b$の解を計算しなさい。

ヒント:

  • numpy.linalg.inv()を利用して行列の逆行列を計算できれば、連立一次方程式の解を算出できます。
  • numpy.linalg.solve()を調べて、

$$ Ax=b, \quad A = \left( \begin{array}{ccc} 2 & 1 & 0 \\ 1 & 2 & 1 \\ 0 & 1 & 2 \\ \end{array} \right) ,\quad b = \left( \begin{array}{c} 1\\ 2\\ 3\\ \end{array} \right) $$