numpyは、多次元配列を扱う数値演算ライブラリです。ここでは、numpyをインストールして基本的な操作方法を確認します。
目次
インストール
pipenv を利用している場合、以下のようにインストールします。
$ pipenv install numpyプログラムから利用するにはimportが必要です。
慣習的にnumpyをimportするときは np と別名をつけます。
import numpy as np
print(np.array([0, 1, 2])) # [0 1 2]ndarrayオブジェクトの生成
ndarrayオブジェクト
numpyは ndarray というクラスを扱います。
numpyの arrayメソッド の戻り値は、 ndarrayクラス のオブジェクトになります。
>>> print(np.array([0, 1, 2]).__class__.__name__)
ndarrayhelp関数 で ndarrayクラス の説明を確認できます。
help(np.array([0, 1, 2]))array|一次元配列
>>> np.array([0, 1, 2])
array([0, 1, 2])array|二次元配列
>>> np.array([[0, 1, 2], [3, 4, 5]])
array([[0, 1, 2],
[3, 4, 5]])array|三次元配列
>>> np.array([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [8, 9, 10]]])
array([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 8, 9, 10]]])zeros|0で初期化されたndarray
>>> np.zeros((3, 4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>>
>>> np.zeros((3, 4), dtype=np.int16)
array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]], dtype=int16)ones|1で初期化されたndarray
>>> np.ones((3, 4))
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
>>>
>>> np.ones((3, 4), dtype=np.int16)
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]], dtype=int16)arange|連番(開始, 終了, ステップ)
numpy.arange([start, ]stop, [step, ]dtype=None)>>> np.arange(3)
array([0, 1, 2])
>>>
>>> np.arange(5)
array([0, 1, 2, 3, 4])
>>>
>>> np.arange(2, 5)
array([2, 3, 4])
>>>
>>> np.arange(0, 30, 5)
array([ 0, 5, 10, 15, 20, 25])
>>>
>>> np.arange(0, 3, .5)
array([0. , 0.5, 1. , 1.5, 2. , 2.5])linspace|連番(開始, 終了, 要素数)
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)>>> np.linspace(1, 5, 5)
array([1., 2., 3., 4., 5.])
>>>
>>> np.linspace(1, 2, 5)
array([1. , 1.25, 1.5 , 1.75, 2. ])numpy.randomモジュール|乱数
- rand
- 0から1の範囲でランダムな数値を出力します。
- randn
- 標準正規分布(平均値0、標準偏差1)でランダムな数値を出力します。
>>> np.random.rand()
0.9648441374742954
>>> np.random.randn()
-1.0407926498684088>>> np.random.rand(2, 3)
array([[0.34497556, 0.82011048, 0.72948862],
[0.22415192, 0.34738009, 0.68770817]])
>>> np.random.randn(2, 3)
array([[ 1.08734939, -0.5422097 , 0.03434921],
[ 0.36904612, -0.76273892, 0.1990645 ]])rand
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
x = np.random.rand(10000)
dfx = pd.DataFrame(x)
print(dfx.describe())
# 0
# count 10000.000000
# mean 0.496157
# std 0.288810
# min 0.000017
# 25% 0.244721
# 50% 0.489199
# 75% 0.751274
# max 0.999902
plt.hist(x, bins=100)
plt.show()
randn
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
y = np.random.randn(10000)
dfy = pd.DataFrame(y)
print(dfy.describe())
# 0
# count 10000.000000
# mean 0.000885
# std 1.004407
# min -3.828600
# 25% -0.687603
# 50% 0.000938
# 75% 0.690210
# max 4.196197
plt.hist(y, bins=100)
plt.show()
reshape|次元を変更
一次元配列を 3×4の二次元配列に変形してみます。
>>> np.arange(12).reshape(4, 3)
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])一次元配列を 3×3×3の三次元配列に変形してみます。
>>> np.arange(27).reshape(3, 3, 3)
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]]])一次元配列を 100×100 の二次元配列に変形してみます。
>>> np.arange(10000).reshape(100, 100)
array([[ 0, 1, 2, ..., 97, 98, 99],
[ 100, 101, 102, ..., 197, 198, 199],
[ 200, 201, 202, ..., 297, 298, 299],
...,
[9700, 9701, 9702, ..., 9797, 9798, 9799],
[9800, 9801, 9802, ..., 9897, 9898, 9899],
[9900, 9901, 9902, ..., 9997, 9998, 9999]])ndarrayクラスの主な属性
ndim|次元数
配列の次元数(dimension)を取得します。
>>> np.array([0, 1, 2]).ndim
1
>>> np.array([[0, 1, 2], [3, 4, 5]]).ndim
2
>>> np.array([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [8, 9, 10]]]).ndim
3shape|各次元の配列サイズ
>>> np.array([0, 1, 2]).shape
(3,)
>>> np.array([0, 1, 2, 3, 4, 5]).shape
(6,)>>> np.array([[0, 1], [3, 4], [5, 6], [7, 8]])
array([[0, 1],
[3, 4],
[5, 6],
[7, 8]])
>>> np.array([[0, 1], [3, 4], [5, 6], [7, 8]]).shape
(4, 2)>>> np.array([[0, 1, 2], [3, 4, 5]])
array([[0, 1, 2],
[3, 4, 5]])
>>> np.array([[0, 1, 2], [3, 4, 5]]).shape
(2, 3)>>> np.arange(24).reshape(2, 3, 4)
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]]])
>>>
>>> np.arange(24).reshape(2, 3, 4).shape
(2, 3, 4)size|要素数
>>> np.array([0, 1, 2]).size
3
>>> np.array([0, 1, 2, 3]).size
4
>>> np.array([[0, 1, 2], [3, 4, 5]]).size
6
>>> np.array([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [8, 9, 10]]]).size
12dtype|要素の型
デフォルト
[] で指定する値によって変わります。
>>> np.array([0, 1, -1])
array([ 0, 1, -1])
>>> np.array([0, 1, -1]).dtype
dtype('int64')>>> np.array([0, 1, -1, 0.5])
array([ 0. , 1. , -1. , 0.5])
>>> np.array([0, 1, -1, 0.5]).dtype
dtype('float64')32ビットの符号付き整数
>>> np.array([0, 1, -1, 0.5], dtype = 'int32')
array([ 0, 1, -1, 0], dtype=int32)
>>> np.array([0, 1, -1, 0.5], dtype = 'int32').dtype
dtype('int32')32ビットの符号なし整数
>>> np.array([0, 1, -1, 0.5], dtype = 'uint32')
array([ 0, 1, 4294967295, 0], dtype=uint32)
>>> np.array([0, 1, -1, 0.5], dtype = 'uint32').dtype
dtype('uint32')32ビットの浮動小数点数
>>> np.array([0, 1, -1, 0.5], dtype = 'float32')
array([ 0. , 1. , -1. , 0.5], dtype=float32)
>>> np.array([0, 1, -1, 0.5], dtype = 'float32').dtype
dtype('float32')真偽値
>>> np.array([0, 1, -1, 0.5], dtype = 'bool')
array([False, True, True, True])
>>> np.array([0, 1, -1, 0.5], dtype = 'bool').dtype
dtype('bool')計算
配列 と スカラー
>>> np.array([[1, 2, 3], [4, 5, 6]]) + 2
array([[3, 4, 5],
[6, 7, 8]])
>>> np.array([[1, 2, 3], [4, 5, 6]]) - 2
array([[-1, 0, 1],
[ 2, 3, 4]])
>>> np.array([[1, 2, 3], [4, 5, 6]]) * 2
array([[ 2, 4, 6],
[ 8, 10, 12]])
>>> np.array([[1, 2, 3], [4, 5, 6]]) / 2
array([[0.5, 1. , 1.5],
[2. , 2.5, 3. ]])配列 と 配列
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>>
>>> a + b
array([[ 2, 4, 6],
[ 8, 10, 12]])
>>> a - b
array([[0, 0, 0],
[0, 0, 0]])>>> a = np.array([1, 2, 3])
>>> b = np.array([[2], [3], [4]])
>>> a * b
array([[ 2, 4, 6],
[ 3, 6, 9],
[ 4, 8, 12]])行列の積|dotメソッド
行列の積を求めるには、dotメソッド を利用します。
(1×3行列)(3×1行列)
>>> a = np.array([1, 2, 3])
>>> b = np.array([[2], [3], [4]])
array([1, 2, 3])
>>> b
array([[2],
[3],
[4]])
>>> np.dot(a, b)
array([20])
// (1 × 2) + (2 × 3) + (3 × 4) = 2 + 6 + 12 = 20(1×3行列)(3×2行列)
>>> a = np.array([1, 2, 3])
>>> b = np.array([[[2], [3], [4]], [[1], [1], [1]]])
>>>
>>> a
array([1, 2, 3])
>>> b
array([[[2],
[3],
[4]],
[[1],
[1],
[1]]])
>>>
>>> np.dot(a, b)
array([[20],
[ 6]])
// (1 × 2) + (2 × 3) + (3 × 4) = 2 + 6 + 12 = 20
// (1 × 1) + (2 × 1) + (3 × 1) = 1 + 2 + 3 = 6ブロードキャスト
ブロードキャストという機能があり、要素数が足りないとき、自動で行・列を揃えてくれます。
まず、ブロードキャストを利用しないで、全ての要素に10を加えてみます。
>>> a = np.array([0, 1, 2, 3, 4, 5])
>>> b = np.array([10, 10, 10, 10, 10, 10])
>>>
>>> a + b
array([10, 11, 12, 13, 14, 15])次に、ブロードキャストを利用します。
>>> a = np.array([0, 1, 2, 3, 4, 5])
>>> a + 10
array([10, 11, 12, 13, 14, 15])統計
合計
>>> np.array([[0, 1, 2], [3, 4, 5]]).sum()
15最小値
>>> np.array([[0, 1, 2], [3, 4, 5]]).min()
0最大値
>>> np.array([[0, 1, 2], [3, 4, 5]]).max()
5平均値
>>> np.array([[0, 1, 2], [3, 4, 5]]).mean()
2.5要素取得(添字とスライス)
Pythonのリストと同様の考えで以下操作ができます。
添字で特定要素を取得スライスで特定範囲の要素を取得
一次元配列
>>> a = np.array([0, 1, 2, 3, 4, 5])
>>>
>>> a[0]
0
>>> a[1:3]
array([1, 2])スライスした値を別の変数に格納した際、注意点があります。
>>> a = np.array([0, 1, 2, 3, 4, 5])
>>> a
array([0, 1, 2, 3, 4, 5])
>>>
>>> b = a[1:4]
>>> b
array([1, 2, 3])
>>>
>>> b[1] = 100
>>> b
array([ 1, 100, 3])
>>> a
array([ 0, 1, 100, 3, 4, 5])上記のように、変数a の値も更新されます。変数a の値は更新させたくない場合、copyメソッド を利用します。
>>> a = np.array([0, 1, 2, 3, 4, 5])
>>> a
array([0, 1, 2, 3, 4, 5])
>>>
>>> b = a[1:4].copy()
>>> b
array([1, 2, 3])
>>>
>>> b[1] = 100
>>> b
array([ 1, 100, 3])
>>> a
array([0, 1, 2, 3, 4, 5])二次元配列
>>> a = np.arange(24).reshape(4, 6)
>>>
>>> a
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]])
>>> a[0][2]
2
>>>
>>> a
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]])
>>> a[:, 2:4]
array([[ 2, 3],
[ 8, 9],
[14, 15],
[20, 21]])
>>>
>>> a
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]])
>>> a[0:2, 2:4]
array([[2, 3],
[8, 9]])